Created
February 4, 2014 21:26
-
-
Save SirTony/8812672 to your computer and use it in GitHub Desktop.
This is a port of the XNA generic resource pool (http://www.xnawiki.com/index.php/Generic_Resource_Pool) in the D programming language.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module resourcepool; | |
import std.traits; | |
public final class Pool( TClass ) if( !is( TClass == struct ) && !( isIntegral!TClass || isFloatingPoint!TClass ) && !is( TClass == bool ) && !isSomeChar!TClass ) | |
{ | |
private alias void delegate( TClass ) Action; | |
private alias bool delegate( TClass ) Predicate; | |
private alias TClass delegate() Func; | |
private const int RESIZE_AMOUNT = 10; | |
private bool mCanResize; | |
private TClass[] mItems; | |
private Predicate mValidate; | |
private Func mAllocate; | |
private Action mInitialize; | |
private Action mDeinitialize; | |
private int mInvalidCount; | |
public Action Initialize() @property | |
{ | |
return this.mInitialize; | |
} | |
public void Initialize( Action iAction ) @property | |
{ | |
this.mInitialize = iAction; | |
} | |
public Action Deinitialize() @property | |
{ | |
return this.mDeinitialize; | |
} | |
public void Deinitialize( Action iAction ) @property | |
{ | |
this.mDeinitialize = iAction; | |
} | |
public int ValidCount() @property | |
{ | |
return this.mItems.length - this.mInvalidCount; | |
} | |
public int InvalidCount() @property | |
{ | |
return this.mInvalidCount; | |
} | |
private void InvalidCount( int count ) @property | |
{ | |
this.mInvalidCount = count; | |
} | |
public TClass opIndex( int index ) | |
{ | |
index += this.mInvalidCount; | |
if( index < this.mInvalidCount || index >= this.mItems.length ) | |
throw new Exception( "The index must be less than or equal to ValidCount." ); | |
return this.mItems[index]; | |
} | |
public this( int initialSize, bool canResize, Predicate validator, Func allocator ) | |
in | |
{ | |
assert( initialSize < 1, "initialSize must be at least 1." ); | |
assert( validator !is null, "validator cannot be null." ); | |
assert( allocator !is null, "allocator cannot be null." ); | |
} | |
body | |
{ | |
this.mCanResize = canResize; | |
this.mItems = new TClass[initialSize]; | |
this.mInvalidCount = this.mItems.length; | |
this.mValidate = validator; | |
this.mAllocate = allocator; | |
} | |
public void CleanUp() | |
{ | |
for( int i = this.mInvalidCount; i < this.mItems.length; ++i ) | |
{ | |
TClass obj = this.mItems[i]; | |
if( this.mValidate( obj ) ) | |
continue; | |
if( i != this.mInvalidCount ) | |
{ | |
this.mItems[i] = this.mItems[this.mInvalidCount]; | |
this.mItems[this.mInvalidCount] = obj; | |
} | |
if( this.Deinitialize !is null ) | |
this.Deinitialize()( obj ); | |
++this.mInvalidCount; | |
} | |
} | |
public TClass New() | |
{ | |
if( this.mInvalidCount == 0 ) | |
{ | |
if( !this.mCanResize ) | |
return null; | |
this.mItems ~= new TClass[RESIZE_AMOUNT]; | |
this.mInvalidCount += RESIZE_AMOUNT; | |
} | |
--this.mInvalidCount; | |
TClass obj = this.mItems[this.mInvalidCount]; | |
if( obj is null ) | |
{ | |
obj = this.mAllocate(); | |
if( obj is null ) | |
throw new Exception( "Error allocating new resource." ); | |
this.mItems[this.mInvalidCount] = obj; | |
} | |
if( this.Initialize !is null ) | |
this.Initialize()( obj ); | |
return obj; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment