From 74e6eacd159f61c2c8f8ea90ec3c90062791da63 Mon Sep 17 00:00:00 2001 From: spartanj Date: Sun, 1 Aug 2010 18:16:27 -0300 Subject: [PATCH] Added Mersenne Twister pseudo-random number generator ( really usefull and fast for some type of games if you want a deterministic random number generator ). Reimplemented the tResourceManager, now uses std::list instead of std::map, and added some new methods. cShapeGroupManager and cShapeGroup now inherits from tResourceManager. Rolled back eeUint and eeInt, now are fine again ( it was changed for testing ). --- ee.linux.cbp | 2 + src/base.hpp | 18 +-- src/ee.h | 11 +- src/graphics/base.hpp | 1 + src/graphics/cfontmanager.cpp | 6 +- src/graphics/cfontmanager.hpp | 1 - src/graphics/cglobalshapegroup.cpp | 2 +- src/graphics/cshaderprogrammanager.cpp | 9 +- src/graphics/cshaderprogrammanager.hpp | 1 - src/graphics/cshapegroup.cpp | 114 +-------------- src/graphics/cshapegroup.hpp | 37 +---- src/graphics/cshapegroupmanager.cpp | 55 +------- src/graphics/cshapegroupmanager.hpp | 16 +-- src/math/cmtrand.cpp | 184 +++++++++++++++++++++++++ src/math/cmtrand.hpp | 142 +++++++++++++++++++ src/system/tresourcemanager.hpp | 135 +++++++++++++----- 16 files changed, 463 insertions(+), 271 deletions(-) create mode 100755 src/math/cmtrand.cpp create mode 100755 src/math/cmtrand.hpp diff --git a/ee.linux.cbp b/ee.linux.cbp index bbea2fe6e..54bbeb7ab 100644 --- a/ee.linux.cbp +++ b/ee.linux.cbp @@ -174,6 +174,8 @@ + + diff --git a/src/base.hpp b/src/base.hpp index 38c0ef008..49bba7e90 100644 --- a/src/base.hpp +++ b/src/base.hpp @@ -81,18 +81,18 @@ #define EE_CALL #endif -#define EE_CLOCKS_PER_SEC 1000000l - -#define eeARRAY_SIZE(__array) ( sizeof(__array) / sizeof(__array[0]) ) -#define eeSAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } } -#define eeSAFE_FREE(p) { if(p) { free ( (void*)p );(p)=NULL; } } -#define eeSAFE_DELETE_ARRAY(p) { if(p) { delete[](p); (p)=NULL; } } - namespace EE { + #define EE_CLOCKS_PER_SEC 1000000l + + #define eeARRAY_SIZE(__array) ( sizeof(__array) / sizeof(__array[0]) ) + #define eeSAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } } + #define eeSAFE_FREE(p) { if(p) { free ( (void*)p );(p)=NULL; } } + #define eeSAFE_DELETE_ARRAY(p) { if(p) { delete[](p); (p)=NULL; } } + typedef float eeFloat; //! The internal floating point used on EE++. \n This can help to improve compatibility with some platforms. \n And helps for an easy change from single precision to double precision. typedef double eeDouble; //! The internal double floating point. It's only used when the engine needs some very high precision floating point ( for example the timer ) - typedef unsigned long eeUint; - typedef signed long eeInt; + typedef unsigned int eeUint; + typedef signed int eeInt; const eeFloat PI = 3.141592654f; const eeFloat TwoPI = 6.283185308f; diff --git a/src/ee.h b/src/ee.h index e7f2378ab..c9da83888 100755 --- a/src/ee.h +++ b/src/ee.h @@ -9,12 +9,14 @@ The project aims to provide a simple and powerfull framework that takes advantage of C++, OpenGL, OpenAL, SDL and more. Thanks to: \n + * Sean Barrett for the stb_vorbis and stb_image libraries. \n + * Sam Latinga for Simple DirectMedia Layer library. \n + * Lucian Wischik for ziputils library. \n * Jonathan Dummer for the Simple OpenGL Image Library. \n - * SFML staff, a great library that use as reference for the development. \n + * Laurent Gomila for the SFML library ( eepp audio module is based on the SFML audio module ) \n * OGRE staff for the Timer implementation \n - * Sean Barrett for the stb_vorbis library. \n - * Amir 'Genjix' Taaki for the information of SDL_Collide.h. - * And a lot more people! :P + * Amir 'Genjix' Taaki for the information of SDL_Collide.h. \n + * And a lot more people! **/ // General includes and declarations @@ -42,6 +44,7 @@ // Math #include "math/math.hpp" + #include "math/cmtrand.hpp" using namespace EE::Math; // System diff --git a/src/graphics/base.hpp b/src/graphics/base.hpp index 4918af0d5..c58f4aa3f 100644 --- a/src/graphics/base.hpp +++ b/src/graphics/base.hpp @@ -23,6 +23,7 @@ using namespace EE::Math; #include "../system/singleton.hpp" #include "../system/clog.hpp" #include "../system/cpack.hpp" +#include "../system/tresourcemanager.hpp" using namespace EE::System; #include "renders.hpp" diff --git a/src/graphics/cfontmanager.cpp b/src/graphics/cfontmanager.cpp index 118382876..1319e5736 100644 --- a/src/graphics/cfontmanager.cpp +++ b/src/graphics/cfontmanager.cpp @@ -2,10 +2,10 @@ namespace EE { namespace Graphics { -cFontManager::cFontManager() { +cFontManager::cFontManager() { } - + cFontManager::~cFontManager() { } -}} \ No newline at end of file +}} diff --git a/src/graphics/cfontmanager.hpp b/src/graphics/cfontmanager.hpp index ecef03fc5..0974cbc64 100644 --- a/src/graphics/cfontmanager.hpp +++ b/src/graphics/cfontmanager.hpp @@ -3,7 +3,6 @@ #include "base.hpp" #include "cfont.hpp" -#include "../system/tresourcemanager.hpp" namespace EE { namespace Graphics { diff --git a/src/graphics/cglobalshapegroup.cpp b/src/graphics/cglobalshapegroup.cpp index 13dd0ab74..d9bb5a018 100644 --- a/src/graphics/cglobalshapegroup.cpp +++ b/src/graphics/cglobalshapegroup.cpp @@ -4,7 +4,7 @@ namespace EE { namespace Graphics { cGlobalShapeGroup::cGlobalShapeGroup() : - cShapeGroup( "global", 64 ) + cShapeGroup( "global" ) { } diff --git a/src/graphics/cshaderprogrammanager.cpp b/src/graphics/cshaderprogrammanager.cpp index 16eecbbe8..a6678d803 100644 --- a/src/graphics/cshaderprogrammanager.cpp +++ b/src/graphics/cshaderprogrammanager.cpp @@ -11,13 +11,10 @@ cShaderProgramManager::~cShaderProgramManager() } void cShaderProgramManager::Reload() { - std::map::iterator it; + std::list::iterator it; - for ( it = mResources.begin(); it != mResources.end(); it++ ) { - cShaderProgram * sp = reinterpret_cast< cShaderProgram* > ( it->second ); - - sp->Reload(); - } + for ( it = mResources.begin(); it != mResources.end(); it++ ) + (*it)->Reload(); } }} diff --git a/src/graphics/cshaderprogrammanager.hpp b/src/graphics/cshaderprogrammanager.hpp index 5a55a8e41..fbc20c659 100644 --- a/src/graphics/cshaderprogrammanager.hpp +++ b/src/graphics/cshaderprogrammanager.hpp @@ -3,7 +3,6 @@ #include "base.hpp" #include "cshaderprogram.hpp" -#include "../system/tresourcemanager.hpp" namespace EE { namespace Graphics { diff --git a/src/graphics/cshapegroup.cpp b/src/graphics/cshapegroup.cpp index dcc8ef2db..5d0613f08 100644 --- a/src/graphics/cshapegroup.cpp +++ b/src/graphics/cshapegroup.cpp @@ -2,20 +2,13 @@ namespace EE { namespace Graphics { -cShapeGroup::cShapeGroup( const std::string& name, const Uint32& Allocate ) : - mCount(0) +cShapeGroup::cShapeGroup( const std::string& name ) : + tResourceManager ( true ) { Name( name ); - this->Allocate( Allocate ); } cShapeGroup::~cShapeGroup() { - Destroy(); -} - -void cShapeGroup::Destroy() { - for ( Uint32 i = 0; i < mShapes.size(); i++ ) - RemoveAt(i); } const std::string& cShapeGroup::Name() const { @@ -31,100 +24,8 @@ const Uint32& cShapeGroup::Id() const { return mId; } -void cShapeGroup::Allocate( const Uint32& Size ) { - if ( Size > mShapes.size() ) { - mShapes.resize( Size, NULL ); - - for ( eeUint i = 0; i < mShapes.size(); i++ ) - mVectorFreeSlots.push( i ); - } -} - -Uint32 cShapeGroup::FindFreeSlot() { - if ( mVectorFreeSlots.size() ) { - Uint32 Pos = mVectorFreeSlots.front(); - - mVectorFreeSlots.pop(); - - return Pos; - } - - mShapes.push_back( NULL ); - - return mShapes.size() - 1; -} - -Uint32 cShapeGroup::GetIndex( const Uint32& Hash ) { - if ( 0 != Hash ) { - for ( Uint32 i = 0; i < mShapes.size(); i++ ) { - if ( NULL != mShapes[i] && mShapes[i]->Id() == Hash ) - return i; - } - } - - return SHAPE_NONE; -} - -Uint32 cShapeGroup::GetIndex( const std::string& Name ) { - return GetIndex( MakeHash( Name ) ); -} - -cShape * cShapeGroup::GetAt( const Uint32& Index ) { - // assert here - - return mShapes[ Index ]; -} - -cShape * cShapeGroup::GetById( const Uint32& Hash ) { - if ( 0 != Hash ) { - for ( Uint32 i = mShapes.size() - 1; i >= 0; i-- ) { - if ( NULL != mShapes[i] && mShapes[i]->Id() == Hash ) - return mShapes[i]; - } - } - - return NULL; -} - -cShape * cShapeGroup::GetByName( const std::string& Name ) { - return GetById( MakeHash( Name ) ); -} - -bool cShapeGroup::RemoveById( const Uint32& Hash ) { - Uint32 Pos = GetIndex( Hash ); - - if ( Pos != SHAPE_NONE ) - return RemoveAt( Pos ); - - return false; -} - -bool cShapeGroup::RemoveAt( const Uint32& Index ) { - if ( Index < mShapes.size() ) { - eeSAFE_DELETE( mShapes[ Index ] ); - - mVectorFreeSlots.push( Index ); - - mCount--; - - return true; - } - - return false; -} - -bool cShapeGroup::RemoveByName( const std::string& Name ) { - return RemoveById( MakeHash( Name ) ); -} - cShape * cShapeGroup::Add( cShape * Shape ) { - if ( NULL != Shape ) { - mShapes[ FindFreeSlot() ] = Shape; - - mCount++; - } - - return Shape; + return tResourceManager::Add( Shape ); } cShape * cShapeGroup::Add( const Uint32& TexId, const std::string& Name ) { @@ -143,13 +44,4 @@ cShape * cShapeGroup::Add( const Uint32& TexId, const eeRecti& SrcRect, const ee return Add( new cShape( TexId, SrcRect, DestWidth, DestHeight, OffsetX, OffsetY, Name ) ); } -void cShapeGroup::Clear() { - for ( Uint32 i = 0; i < mShapes.size(); i++ ) - RemoveAt(i); -} - -const Int32& cShapeGroup::Count() const { - return mCount; -} - }} diff --git a/src/graphics/cshapegroup.hpp b/src/graphics/cshapegroup.hpp index c6507dd24..21601b69a 100644 --- a/src/graphics/cshapegroup.hpp +++ b/src/graphics/cshapegroup.hpp @@ -8,32 +8,12 @@ namespace EE { namespace Graphics { -class EE_API cShapeGroup { +class EE_API cShapeGroup : public tResourceManager { public: - cShapeGroup( const std::string& name = "", const Uint32& Allocate = 0 ); + cShapeGroup( const std::string& name = "" ); ~cShapeGroup(); - void Allocate( const Uint32& Size ); - - void Destroy(); - - Uint32 GetIndex( const Uint32& Hash ); - - Uint32 GetIndex( const std::string& Name ); - - cShape * GetAt( const Uint32& Index ); - - cShape * GetById( const Uint32& Hash ); - - cShape * GetByName( const std::string& Name ); - - bool RemoveById( const Uint32& Hash ); - - bool RemoveAt( const Uint32& Index ); - - bool RemoveByName( const std::string& Name ); - cShape * Add( cShape * Shape ); cShape * Add( const Uint32& TexId, const std::string& Name = "" ); @@ -44,23 +24,14 @@ class EE_API cShapeGroup { cShape * Add( const Uint32& TexId, const eeRecti& SrcRect, const eeFloat& DestWidth, const eeFloat& DestHeight, const eeFloat& OffsetX, const eeFloat& OffsetY, const std::string& Name = "" ); - void Clear(); - - const Int32& Count() const; - const std::string& Name() const; void Name( const std::string& name ); const Uint32& Id() const; protected: - std::string mName; - Uint32 mId; - std::vector mShapes; - std::queue mVectorFreeSlots; - Int32 mCount; - - Uint32 FindFreeSlot(); + std::string mName; + Uint32 mId; }; }} diff --git a/src/graphics/cshapegroupmanager.cpp b/src/graphics/cshapegroupmanager.cpp index 8ee260e2d..5ee30259d 100644 --- a/src/graphics/cshapegroupmanager.cpp +++ b/src/graphics/cshapegroupmanager.cpp @@ -3,56 +3,13 @@ namespace EE { namespace Graphics { -cShapeGroupManager::cShapeGroupManager() { +cShapeGroupManager::cShapeGroupManager() : + tResourceManager( false ) +{ Add( cGlobalShapeGroup::instance() ); } cShapeGroupManager::~cShapeGroupManager() { - Destroy(); -} - -void cShapeGroupManager::Destroy() { - std::list::iterator it; - - for ( it = mGroups.begin(); it != mGroups.end(); it++ ) - eeSAFE_DELETE( (*it) ); -} - -void cShapeGroupManager::Add( cShapeGroup * Group ) { - if ( NULL != Group ) - mGroups.push_back( Group ); -} - -void cShapeGroupManager::Remove( cShapeGroup * Group, bool Delete ) { - if ( NULL != Group ) { - mGroups.remove( Group ); - - if ( Delete ) - eeSAFE_DELETE( Group ); - } -} - -Uint32 cShapeGroupManager::Count() { - return mGroups.size(); -} - -cShapeGroup * cShapeGroupManager::GetByName( const std::string& Name ) { - return GetById( MakeHash( Name ) ); -} - -cShapeGroup * cShapeGroupManager::GetById( const Uint32& Id ) { - std::list::iterator it; - - cShapeGroup * tGroup = NULL; - - for ( it = mGroups.begin(); it != mGroups.end(); it++ ) { - tGroup = (*it); - - if ( tGroup->Id() == Id ) - return tGroup; - } - - return NULL; } cShape * cShapeGroupManager::GetShapeByName( const std::string& Name ) { @@ -62,12 +19,10 @@ cShape * cShapeGroupManager::GetShapeByName( const std::string& Name ) { cShape * cShapeGroupManager::GetShapeById( const Uint32& Id ) { std::list::iterator it; - cShapeGroup * tGroup = NULL; cShape * tShape = NULL; - for ( it = mGroups.begin(); it != mGroups.end(); it++ ) { - tGroup = (*it); - tShape = tGroup->GetById( Id ); + for ( it = mResources.begin(); it != mResources.end(); it++ ) { + tShape = (*it)->GetById( Id ); if ( NULL != tShape ) return tShape; diff --git a/src/graphics/cshapegroupmanager.hpp b/src/graphics/cshapegroupmanager.hpp index 41593820e..db77fe88d 100644 --- a/src/graphics/cshapegroupmanager.hpp +++ b/src/graphics/cshapegroupmanager.hpp @@ -7,30 +7,16 @@ namespace EE { namespace Graphics { -class EE_API cShapeGroupManager : public cSingleton { +class EE_API cShapeGroupManager : public tResourceManager, public cSingleton { friend class cSingleton; public: cShapeGroupManager(); virtual ~cShapeGroupManager(); - void Add( cShapeGroup * Group ); - - void Remove( cShapeGroup * Group, bool Delete = true ); - - Uint32 Count(); - - cShapeGroup * GetByName( const std::string& Name ); - - cShapeGroup * GetById( const Uint32& Id ); - cShape * GetShapeByName( const std::string& Name ); cShape * GetShapeById( const Uint32& Id ); - - void Destroy(); - protected: - std::list mGroups; }; }} diff --git a/src/math/cmtrand.cpp b/src/math/cmtrand.cpp new file mode 100755 index 000000000..c6faac399 --- /dev/null +++ b/src/math/cmtrand.cpp @@ -0,0 +1,184 @@ +#include "cmtrand.hpp" + +namespace EE { namespace Math { + +MTRand::MTRand( const Uint32 oneSeed ) { + Seed( oneSeed ); +} + +MTRand::MTRand() { + Seed(); +} + +MTRand::MTRand( const MTRand& o ) { + register const Uint32 *t = o.mState; + register Uint32 * s = mState; + register int i = N; + + for ( ; i--; *s++ = *t++ ) + { + } + + mLeft = o.mLeft; + + mNext = &mState[ N - mLeft ]; +} + +void MTRand::Initialize( const Uint32 seed ) { + register Uint32 *s = mState; + + register Uint32 *r = mState; + + register Int32 i = 1; + + *s++ = seed & 0xffffffffUL; + + for ( ; i < N; ++i ) { + *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL; + r++; + } +} + +void MTRand::Reload() { + static const int MmN = int(M) - int(N); + + register Uint32 *p = mState; + + register int i; + + for ( i = N - M; i--; ++p ) + *p = Twist( p[M], p[0], p[1] ); + + for ( i = M; --i; ++p ) + *p = Twist( p[MmN], p[0], p[1] ); + + *p = Twist( p[MmN], p[0], mState[0] ); + + mLeft = N, mNext = mState; +} + +void MTRand::Seed( const Uint32 oneSeed ) { + Initialize( oneSeed ); + Reload(); +} + +void MTRand::Seed() { + Seed( 0xFEDCBA09 ); +} + +Uint32 MTRand::hiBit( const Uint32 u ) const { + return u & 0x80000000UL; +} + +Uint32 MTRand::loBit( const Uint32 u ) const { + return u & 0x00000001UL; +} + +Uint32 MTRand::loBits( const Uint32 u ) const { + return u & 0x7fffffffUL; +} + +Uint32 MTRand::MixBits( const Uint32 u, const Uint32 v ) const { + return hiBit(u) | loBits(v); +} + +Uint32 MTRand::Magic( const Uint32 u ) const { + return loBit(u) ? 0x9908b0dfUL : 0x0UL; +} + +Uint32 MTRand::Twist( const Uint32 m, const Uint32 s0, const Uint32 s1 ) const { + return m ^ ( MixBits( s0, s1 )>>1 ) ^ Magic(s1); +} + +Uint32 MTRand::Randi() { + if ( mLeft == 0 ) + Reload(); + + --mLeft; + + register Uint32 s1; + s1 = *mNext++; + s1 ^= (s1 >> 11); + s1 ^= (s1 << 7) & 0x9d2c5680UL; + s1 ^= (s1 << 15) & 0xefc60000UL; + + return ( s1 ^ (s1 >> 18) ); +} + +Uint32 MTRand::Randi( const Uint32 n ) { + Uint32 used = n; + used |= used >> 1; + used |= used >> 2; + used |= used >> 4; + used |= used >> 8; + used |= used >> 16; + + Uint32 i; + + do { + i = Randi() & used; + } while ( i > n ); + + return i; +} + +eeDouble MTRand::Rand() { + return double( Randi() ) * ( 1.0 / 4294967295.0 ); +} + +eeDouble MTRand::Rand( const eeDouble n ) { + return Rand() * n; +} + +eeFloat MTRand::Randf() { + return (eeFloat)Rand(); +} + +eeFloat MTRand::Randf( const eeFloat n ) { + return (eeFloat)Rand(n); +} + +eeInt MTRand::RandRange( eeInt Min, eeInt Max ) { + return Min + Randi( Max - Min + 1 ); +} + +eeFloat MTRand::RandRange( eeFloat Min, eeFloat Max ) { + return Min + Randf( Max - Min ); +} + +MTRand& MTRand::operator=( const MTRand& o ) { + if ( this == &o ) + return (*this); + + register const Uint32 *t = o.mState; + register Uint32 *s = mState; + register int i = N; + + for ( ; i--; *s++ = *t++ ) + { + } + + mLeft = o.mLeft; + mNext = &mState[ N - mLeft ]; + + return (*this); +} + +void MTRand::Save( Uint32* saveArray ) const { + register const Uint32 *s = mState; + register Uint32 *sa = saveArray; + register int i = N; + for( ; i--; *sa++ = *s++ ) {} + *sa = mLeft; +} + +void MTRand::Load( Uint32 *const loadArray ) { + register Uint32 *s = mState; + register Uint32 *la = loadArray; + register int i = N; + for( ; i--; *s++ = *la++ ) {} + mLeft = *la; + mNext = &mState[N-mLeft]; +} + +}} diff --git a/src/math/cmtrand.hpp b/src/math/cmtrand.hpp new file mode 100755 index 000000000..8e7411e17 --- /dev/null +++ b/src/math/cmtrand.hpp @@ -0,0 +1,142 @@ +// MersenneTwister.h +// Mersenne Twister random number generator -- a C++ class MTRand +// Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus +// Richard J. Wagner v1.1 28 September 2009 wagnerr@umich.edu + +// The Mersenne Twister is an algorithm for generating random numbers. It +// was designed with consideration of the flaws in various other generators. +// The period, 2^19937-1, and the order of equidistribution, 623 dimensions, +// are far greater. The generator is also fast; it avoids multiplication and +// division, and it benefits from caches and pipelines. For more information +// see the inventors' web page at +// http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + +// Reference +// M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally +// Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on +// Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30. + +// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, +// Copyright (C) 2000 - 2009, Richard J. Wagner +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The names of its contributors may not be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +// The original code included the following notice: +// +// When you use this, send an email to: m-mat@math.sci.hiroshima-u.ac.jp +// with an appropriate reference to your work. +// +// It would be nice to CC: wagnerr@umich.edu and Cokus@math.washington.edu +// when you write. + +// Adapted to EE++ ( this is not the original file ). +// Added RandRange. + +#ifndef EE_UTILSCMTRAND_HPP +#define EE_UTILSCMTRAND_HPP + +#include "base.hpp" + +namespace EE { namespace Math { + +class MTRand { + public: + static const Uint32 M = 397; + static const Int32 N = 624; + static const Uint32 SAVE = N + 1; + + MTRand( const Uint32 oneSeed ); + + /** Initialize with a predefined seed */ + MTRand(); + + MTRand( const MTRand& o ); + + MTRand& operator=( const MTRand& o ); + + /** @return integer in [0,2^32-1] */ + Uint32 Randi(); + + /** @return integer in [0,n] for n < 2^32 */ + Uint32 Randi( const Uint32 n ); + + /** @return real number in [0,1] */ + eeDouble Rand(); + + /** @return real number in [0,n] */ + eeDouble Rand( const eeDouble n ); + + /** Set a new seed */ + void Seed( const Uint32 oneSeed ); + + /** Set the default seed */ + void Seed(); + + /** @return float number in [0,1] */ + eeFloat Randf(); + + /** @return float number in [0,n] */ + eeFloat Randf( const eeFloat n ); + + /** @return int number in [Min,Max] */ + eeInt RandRange( eeInt Min, eeInt Max ); + + /** @return float number in [Min,Max] */ + eeFloat RandRange( eeFloat Min, eeFloat Max ); + + /** Save the state to an allocated array */ + void Save( Uint32* saveArray ) const; + + /** Load state from an array */ + void Load( Uint32 *const loadArray ); + protected: + Uint32 mState[N]; + Uint32 * mNext; + eeInt mLeft; + + void Initialize( const Uint32 oneSeed ); + + void Reload(); + + Uint32 hiBit( const Uint32 u ) const; + + Uint32 loBit( const Uint32 u ) const; + + Uint32 loBits( const Uint32 u ) const; + + Uint32 MixBits( const Uint32 u, const Uint32 v ) const; + + Uint32 Magic( const Uint32 u ) const; + + Uint32 Twist( const Uint32 m, const Uint32 s0, const Uint32 s1 ) const; +}; + +}} + +#endif diff --git a/src/system/tresourcemanager.hpp b/src/system/tresourcemanager.hpp index 9e4122b3f..4fff4b961 100644 --- a/src/system/tresourcemanager.hpp +++ b/src/system/tresourcemanager.hpp @@ -8,31 +8,43 @@ namespace EE { namespace System { template class tResourceManager { public: - tResourceManager(); + tResourceManager( bool UniqueId = true ); virtual ~tResourceManager(); - void Add( T * Resource ); + T * Add( T * Resource ); - void Remove( T * Resource ); + bool Remove( T * Resource, bool Delete = true ); + + bool RemoveById( const Uint32& Id, bool Delete = true ); + + bool RemoveByName( const std::string& Name, bool Delete = true ); T * GetByName( const std::string& Name ); - T * GetById( const Uint32& id ); + T * GetById( const Uint32& Id ); Uint32 Count(); + Uint32 Count( const std::string& Name ); + + Uint32 Count( const Uint32& Id ); + void Reload(); - Uint32 Exists( const std::string& name ); + Uint32 Exists( const std::string& Name ); + + Uint32 Exists( const Uint32& Id ); void Destroy(); protected: - std::map mResources; + std::list mResources; + bool mUniqueId; }; template -tResourceManager::tResourceManager() +tResourceManager::tResourceManager( bool UniqueId ) : + mUniqueId( UniqueId ) { } @@ -43,52 +55,84 @@ tResourceManager::~tResourceManager() { template void tResourceManager::Destroy() { - typename std::map::iterator it; + typename std::list::iterator it; for ( it = mResources.begin() ; it != mResources.end(); it++ ) - eeSAFE_DELETE( it->second ); + eeSAFE_DELETE( (*it) ); } template -void tResourceManager::Add( T * Resource ) { - Uint32 c = mResources.count( Resource->Name() ); +T * tResourceManager::Add( T * Resource ) { + if ( NULL != Resource ) { + if ( mUniqueId ) { + Uint32 c = Count( Resource->Id() ); - if ( 0 == c ) { - mResources[ Resource->Name() ] = Resource; - } else { - Resource->Name( Resource->Name() + intToStr( c + 1 ) ); + if ( 0 == c ) { + mResources.push_back( Resource ); - Add( Resource ); - } -} + return Resource; + } else { + Resource->Name( Resource->Name() + intToStr( c + 1 ) ); -template -void tResourceManager::Remove( T * Resource ) { - mResources.erase( Resource->Name() ); -} + return Add( Resource ); + } + } else { + mResources.push_back( Resource ); -template -Uint32 tResourceManager::Exists( const std::string& name ) { - return mResources.count( name ); -} - -template -T * tResourceManager::GetByName( const std::string& Name ) { - typename std::map::iterator it = mResources.find( Name ); - - if ( mResources.end() != it ) { - return it->second; + return Resource; + } } return NULL; } template -T * tResourceManager::GetById( const Uint32& id ) { - typename std::map::iterator it; +bool tResourceManager::Remove( T * Resource, bool Delete ) { + if ( NULL != Resource ) { + mResources.remove( Resource ); - for ( it = mResources.begin(); it != mResources.end(); it++ ) { - T * sp = reinterpret_cast< T* > ( it->second ); + if ( Delete ) + eeSAFE_DELETE( Resource ); + + return true; + } + + return false; +} + +template +bool tResourceManager::RemoveById( const Uint32& Id, bool Delete ) { + return Remove( GetById( Id ), Delete ); +} + +template +bool tResourceManager::RemoveByName( const std::string& Name, bool Delete ) { + return Remove( GetByName( Name ), Delete ); +} + +template +Uint32 tResourceManager::Exists( const std::string& Name ) { + return Count( Name ); +} + +template +Uint32 tResourceManager::Exists( const Uint32& Id ) { + return Count( Id ); +} + +template +T * tResourceManager::GetByName( const std::string& Name ) { + return GetById( MakeHash( Name ) ); +} + +template +T * tResourceManager::GetById( const Uint32& id ) { + typename std::list::reverse_iterator it; + + T * sp = NULL; + + for ( it = mResources.rbegin(); it != mResources.rend(); it++ ) { + sp = (*it); if ( id == sp->Id() ) return sp; @@ -102,6 +146,23 @@ Uint32 tResourceManager::Count() { return mResources.size(); } +template +Uint32 tResourceManager::Count( const Uint32& Id ) { + typename std::list::iterator it; + Uint32 Count = 0; + + for ( it = mResources.begin() ; it != mResources.end(); it++ ) + if ( (*it)->Id() == Id ) + Count++; + + return Count; +} + +template +Uint32 tResourceManager::Count( const std::string& Name ) { + return Count( MakeHash( Name ) ); +} + }} #endif