Advertisement
vexe

Verfices

Apr 30th, 2014
626
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.91 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEngine;
  5. using Object = UnityEngine.Object;
  6.  
  7. public static class Verfices
  8. {
  9.     // I just think doing a: Verfices.Register(this); is nicer than Verfices<Type>.Register(this);
  10.     // That's why I wrapped everything up like that - personal preference, don't like it? get rid of it
  11.  
  12.     public static void Register<T>(T service) where T : class, IService
  13.     {
  14.         VerficesInternal<T>.Register(service);
  15.     }
  16.  
  17.     public static void Unregister<T>(T service) where T : class, IService
  18.     {
  19.         VerficesInternal<T>.Unregister(service);
  20.     }
  21.  
  22.     public static void RemoveServiceType<T>() where T : class, IService
  23.     {
  24.         VerficesInternal<T>.UnregisterAll();
  25.     }
  26.  
  27.     public static T RequestAt<T>(int index) where T : class, IService
  28.     {
  29.         return VerficesInternal<T>.RequestAt(index);
  30.     }
  31.  
  32.     public static T Request<T>() where T : class, IService
  33.     {
  34.         return VerficesInternal<T>.RequestAt(0);
  35.     }
  36.  
  37.     public static List<T> RequestAll<T>() where T : class, IService
  38.     {
  39.         return VerficesInternal<T>.RequestAll();
  40.     }
  41.  
  42.     public static List<T> RequestMany<T>(int n) where T : class, IService
  43.     {
  44.         return VerficesInternal<T>.RequestMany(n);
  45.     }
  46.  
  47.     public static bool HasRegistered<T>(T service) where T : class, IService
  48.     {
  49.         return VerficesInternal<T>.HasRegistered(service);
  50.     }
  51.  
  52.     public static int GetServicesCount<T>() where T : class, IService
  53.     {
  54.         return VerficesInternal<T>.ServicesCount;
  55.     }
  56.  
  57.     public static T CreateService<T>() where T : class, IService
  58.     {
  59.         Type type = typeof(T);
  60.         if (typeof(MonoBehaviour).IsAssignableFrom(type)) {
  61.             var go = new GameObject(type.ToString());
  62.             return go.AddComponent(type) as T;
  63.         }
  64.         return Activator.CreateInstance(type) as T;
  65.     }
  66.  
  67.         // In case you didn't know, doing a:
  68.     // VerficesInternal<SomeService>.Register(...); and VerficesInternal<SomeOTHERService>.Register(...);
  69.     // the compiler will _not_ create two separate classes - they will use the same place in memory!
  70.     // For more info, see Jamie King's: https://www.youtube.com/watch?v=9eZnUk0Gu7M
  71.     private static class VerficesInternal<T> where T : class, IService
  72.     {
  73.         private static List<T> services = new List<T>();
  74.  
  75.         public static int ServicesCount { get { return services.Count; } }
  76.  
  77.         public static void Register(T service)
  78.         {
  79.             if (services.Contains(service))
  80.                 throw new RegistrationException("[Vervices]: Service instance: `" + service + "` has already registered!");
  81.             else services.Add(service);
  82.  
  83.             var mb = service as MonoBehaviour;
  84.             if (mb != null)
  85.                 Object.DontDestroyOnLoad(mb);
  86.         }
  87.  
  88.         // Becareful though - when you register a MonoBehaviour service, it gets marked with DontDestroyOnLoad
  89.         // Unregistering a service, will remove it from the services list so make sure you still have a reference
  90.         // to the service somewhere or else it's a leak
  91.         public static void Unregister(T service)
  92.         {
  93.             services.Remove(service);
  94.         }
  95.  
  96.         public static T RequestAt(int index)
  97.         {
  98.             AssertNotEmpty();
  99.  
  100.             // I know, index could be out of bounds I should probably throw an exception if so.
  101.             // But I think it's not neccessary cause accessing an array/list in an out-of-bounds index
  102.             // will throw the exception anyway...
  103.             return services[index];
  104.         }
  105.  
  106.         public static void UnregisterAll()
  107.         {
  108.             services.Clear();
  109.         }
  110.  
  111.         public static List<T> RequestAll()
  112.         {
  113.             return services;
  114.         }
  115.  
  116.         public static List<T> RequestMany(int n)
  117.         {
  118.             AssertNotEmpty();
  119.  
  120.             if (n > services.Count)
  121.                 throw new InvalidOperationException(string.Format(
  122.                     "There's only {0} services of type {1}, yet requesting {2}",
  123.                     services.Count, typeof(T).Name, n));
  124.  
  125.             return services.Take(n).ToList();
  126.         }
  127.  
  128.         public static bool HasRegistered(T service)
  129.         {
  130.             return services.Contains(service);
  131.         }
  132.  
  133.         private static void AssertNotEmpty()
  134.         {
  135.             if (services.Count == 0)
  136.                 throw new InvalidOperationException("No registered services of type `" + typeof(T).Name + "`");
  137.         }
  138.  
  139.         private class RegistrationException : Exception
  140.         {
  141.             public RegistrationException(string msg) : base(msg) { }
  142.         }
  143.     }
  144. }
  145.  
  146. public interface IService
  147. {
  148.     void Ping();
  149. }
  150.  
  151. using UnityEngine;
  152. public class InventoryMan : MonoBehaviour, IService
  153. {
  154.     void Awake()
  155.     {
  156.         Verfices.Register(this);
  157.     }
  158.     public void Ping()
  159.     {
  160.         Debug.Log(this + ": providing service!");
  161.     }
  162.     void OnDestroy()
  163.     {
  164.         Verfices.Unregister(this);
  165.     }
  166. }
  167.  
  168. using UnityEngine;
  169. public class AtlasMan : MonoBehaviour, IService
  170. {
  171.     void Awake()
  172.     {
  173.         Verfices.Register(this);
  174.     }
  175.     public void Ping()
  176.     {
  177.         Debug.Log(this + ": providing service!");
  178.     }
  179.     void OnDestroy()
  180.     {
  181.         Verfices.Unregister(this);
  182.     }
  183. }
  184.  
  185. using System.Collections.Generic;
  186. using UnityEngine;
  187.  
  188. public class User : MonoBehaviour
  189. {
  190.     void OnGUI()
  191.     {
  192.         if (GUILayout.Button("inventory count"))
  193.             Debug.Log(Verfices.GetServicesCount<InventoryMan>());
  194.  
  195.         if (GUILayout.Button("atlas count"))
  196.             Debug.Log(Verfices.GetServicesCount<AtlasMan>());
  197.  
  198.         if (GUILayout.Button("request inventory"))
  199.             Verfices.Request<InventoryMan>().Ping();
  200.  
  201.         if (GUILayout.Button("request atlas"))
  202.             Verfices.Request<AtlasMan>().Ping();
  203.  
  204.         if (GUILayout.Button("unregister an inventory service"))
  205.             Verfices.Unregister(Verfices.Request<InventoryMan>());
  206.  
  207.         if (GUILayout.Button("unregister an atlas service"))
  208.             Verfices.Unregister(Verfices.Request<AtlasMan>());
  209.  
  210.         if (GUILayout.Button("request all inventories"))
  211.             foreach (var inventory in Verfices.RequestAll<InventoryMan>())
  212.                 inventory.Ping();
  213.  
  214.         if (GUILayout.Button("request all atlas"))
  215.             foreach (var atlas in Verfices.RequestAll<AtlasMan>())
  216.                 atlas.Ping();
  217.  
  218.         if (GUILayout.Button("request 2 atlases"))
  219.             foreach (var atlas in Verfices.RequestMany<AtlasMan>(2))
  220.                 atlas.Ping();
  221.  
  222.         if (GUILayout.Button("request 2 inventories"))
  223.             foreach (var inventory in Verfices.RequestMany<InventoryMan>(2))
  224.                 inventory.Ping();
  225.  
  226.         if (GUILayout.Button("create a new inventory service"))
  227.             Verfices.CreateService<InventoryMan>();
  228.  
  229.         if (GUILayout.Button("create a new atlas service"))
  230.             Verfices.CreateService<AtlasMan>();
  231.     }
  232.  
  233.     void Start()
  234.     {
  235.         //Comment this out if you wanna test the OnGUI stuff
  236.         //Test();
  237.     }
  238.  
  239.     void Test()
  240.     {
  241.         var inventory = Verfices.Request<InventoryMan>();
  242.         var atlas = Verfices.Request<AtlasMan>();
  243.         Debug.Log("Ping test");
  244.         atlas.Ping();
  245.         inventory.Ping();
  246.  
  247.         Debug.Log("Requesting an atlas man, at index 100");
  248.         Verfices.RequestAt<AtlasMan>(100).Ping();
  249.  
  250.         Debug.Log("altas manager RequestMany test: requesting 5 out of " + Verfices.GetServicesCount<AtlasMan>());
  251.         List<AtlasMan> many = Verfices.RequestMany<AtlasMan>(5);
  252.         foreach (var atlasMan in many) {
  253.             atlasMan.Ping();
  254.         }
  255.  
  256.         Debug.Log(string.Format("altas manager RequestMany test: requesting -1 out of {0} (should not get output)", Verfices.GetServicesCount<AtlasMan>()));
  257.         many = Verfices.RequestMany<AtlasMan>(-1);
  258.         foreach (var atlasMan in many) {
  259.             atlasMan.Ping();
  260.         }
  261.  
  262.         Debug.Log("inventory manager RequestAll test, total: " + Verfices.GetServicesCount<InventoryMan>());
  263.         var all = Verfices.RequestAll<InventoryMan>();
  264.         foreach (var inventoryMan in all) {
  265.             inventoryMan.Ping();
  266.         }
  267.  
  268.         Debug.Log("unregistering an instance of the atlas manager, then printing all, current total: " + Verfices.GetServicesCount<AtlasMan>());
  269.         Verfices.Unregister(Verfices.Request<AtlasMan>());
  270.         foreach (var atlasMan in Verfices.RequestAll<AtlasMan>())
  271.             atlasMan.Ping();
  272.  
  273.         Debug.Log("removing the inventory manager service type, and then printing all, shouldn't get anything");
  274.         Verfices.RemoveServiceType<InventoryMan>();
  275.         foreach (var inventoryMan in Verfices.RequestAll<InventoryMan>())
  276.             inventoryMan.Ping();
  277.  
  278.         Debug.Log("removing the atlas manager service type, and then trying to request many, shouldn't get any output");
  279.         Verfices.RemoveServiceType<AtlasMan>();
  280.         foreach (var atlasMan in Verfices.RequestMany<AtlasMan>(10))
  281.             atlasMan.Ping();
  282.     }
  283. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement