From 6d273251556a992bbe7e9166e43e515586c9396f Mon Sep 17 00:00:00 2001 From: gered Date: Thu, 22 Aug 2013 12:33:35 -0400 Subject: [PATCH] remove "new()" generic type constraints, mimic using reflection --- Blarg.GameFramework/Support/ObjectPools.cs | 35 ++++++++++++++++++---- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/Blarg.GameFramework/Support/ObjectPools.cs b/Blarg.GameFramework/Support/ObjectPools.cs index e84b859..e71d073 100644 --- a/Blarg.GameFramework/Support/ObjectPools.cs +++ b/Blarg.GameFramework/Support/ObjectPools.cs @@ -11,40 +11,65 @@ namespace Blarg.GameFramework.Support class ObjectObjectPool : ObjectPool { Type _type; + ConstructorInfo _constructor; - public ObjectObjectPool(Type type) + public ObjectObjectPool(Type type, ConstructorInfo constructor) : base(INITIAL_CAPACITY) { _type = type; + _constructor = constructor; } protected override object Allocate() { - return Activator.CreateInstance(_type); + // TODO: use a compiled lambda expression instead? + // need to check if possible when AOT compiled + return _constructor.Invoke(null); } } static Dictionary _pools = new Dictionary(); + static ConstructorInfo GetParameterlessConstructor(Type type) + { + var constructors = type.GetConstructors(); + for (int i = 0; i < constructors.Length; ++i) + { + if (constructors[i].GetParameters().Length == 0) + return constructors[i]; + } + + return null; + } + static ObjectObjectPool GetPool(Type type) { ObjectObjectPool pool; _pools.TryGetValue(type, out pool); if (pool == null) { - pool = new ObjectObjectPool(type); + // why do we do this instead of just using a "new()" generic type constraint? + // because doing it this way saves us from having to litter that same type + // constraint on every other class method (in other classes) which might be + // using ObjectPools to auto manage their object pools. Sometimes it gets + // a bit restrictive ...0 + var constructor = GetParameterlessConstructor(type); + if (constructor == null) + throw new InvalidOperationException("ObjectPools can only be used for types with parameterless constructors."); + + pool = new ObjectObjectPool(type, constructor); _pools.Add(type, pool); } return pool; } - public static T Take() where T : class, new() + public static T Take() where T : class { var pool = GetPool(typeof(T)); return (T)pool.Take(); } - public static void Free(T obj) where T : class, new() + public static void Free(T obj) where T : class { var pool = GetPool(typeof(T)); pool.Free(obj);