initial commit

This commit is contained in:
cirdan
2008-01-16 11:45:17 +00:00
commit 8f17a3a819
1068 changed files with 384278 additions and 0 deletions

View File

@ -0,0 +1,87 @@
#ifndef BLUECORE_ACTIVATED_H
#define BLUECORE_ACTIVATED_H
namespace BlueCore
{
class Activated
{
private:
bool _Active;
public:
/**
* Default constructor.
* inital state is active
*/
inline Activated()
{
_Active = true;
}
/**
* Constructor.
* @param set inital state
*/
inline Activated(bool state) :
_Active(state )
{
}
/**
* Destructor.
*/
virtual inline ~Activated()
{
}
/**
* Activate the object.
*/
inline void activate()
{
_Active = true;
onActivation();
}
virtual void onActivation()
{
}
/**
* Deactivate the object.
*/
inline void deactivate()
{
_Active = false;
onDeactivation();
}
virtual void onDeactivation()
{
}
/**
* toggles the object's state
*/
inline void toggleActive()
{
if (_Active )
deactivate();
else
activate();
}
/**
* returns the object's state
*/
inline bool isActive()
{
return _Active;
}
};
} // namespace BlueCore
#endif // BLUECORE_ACTIVATED_H

151
engine/Utilities/Buffer.h Normal file
View File

@ -0,0 +1,151 @@
#ifndef BLUECORE_BUFFER_H
#define BLUECORE_BUFFER_H
#include <stdexcept>
namespace BlueCore
{
template<class T>
class Buffer
{
public:
typedef T type;
private:
type *_buffer;
unsigned int _count;
public:
/**
* default constructor
*/
Buffer() :
_buffer( 0 ),
_count( 0 )
{
}
/**
* constructor with initial size
*/
Buffer( unsigned int count ) :
_buffer( 0 ),
_count( 0 )
{
create( count );
}
/**
* destructor
*/
virtual ~Buffer()
{
destroy();
}
/**
* create the buffer
*/
bool create( unsigned int count )
{
destroy();
_buffer = new type[count];
if( _buffer )
{
_count = count;
return true;
}
else
{
return false;
}
}
/**
* destroy the buffer
*/
void destroy()
{
delete [] _buffer;
_buffer = 0;
_count = 0;
}
void resize( unsigned int new_count )
{
type *new_buffer = new type[new_count];
for( unsigned int i = 0; i<_count; i++ )
new_buffer[i] = _buffer[i];
destroy();
_buffer = new_buffer;
_count = new_count;
}
/**
* returns the item count
*/
unsigned int count() const
{
return _count;
}
/**
* returns the buffer size in bytes
*/
unsigned int size() const
{
return _count * sizeof(type);
}
/**
* return a pointer to the data
*/
type *data()
{
return _buffer;
}
/**
* return a pointer to the(const) data
*/
const type *const_data() const
{
return _buffer;
}
/**
* array operator
*/
type &operator[](const unsigned int index)
{
if( index >= _count )
throw std::range_error("Buffer::[] index_out_of_bound!");
return _buffer[index];
}
type &item(const unsigned int index)
{
if( index >= _count )
throw std::range_error("Buffer::[] index_out_of_bound!");
return _buffer[index];
}
const type &const_item(const unsigned int index) const
{
if( index >= _count )
throw std::range_error("Buffer::[] index_out_of_bound!");
return _buffer[index];
}
};
}
#endif

View File

@ -0,0 +1,198 @@
#include "CfgParser.h"
#include "StringUtilities.h"
#include <fstream>
using namespace std;
namespace BlueCore {
void CfgParser::parseFile (const std::string& filename)
{
ifstream file (filename.c_str(), ios::in);
std::string line;
while (file.good())
{
getline (file, line);
parseLine (line);
}
}
void CfgParser::parseLine (const std::string& line)
{
std::string::size_type i (line.find_first_of ('='));
if (i == std::string::npos)
return;
std::string key = trim (string (line, 0, i-1));
std::string value = trim (string (line, i+1));
_Pairs[key] = value;
}
void CfgParser::parse (const char* buffer, unsigned int length)
{
const char* ptr = buffer;
const char* end = buffer + length;
unsigned int l = 0;
while (ptr < end)
{
// find end of line
while (ptr[l] != '\n')
{
l++;
if (ptr + l >= end)
break;
}
parseLine (string(ptr, l));
ptr += l+1;
l = 0;
}
}
double CfgParser::get (const std::string& key, double defaultValue)
{
double value;
if (getDouble (key, value) == false)
return defaultValue;
else
return value;
}
bool CfgParser::getDouble (const std::string& key, double& value)
{
std::map<std::string, std::string>::const_iterator result;
result = _Pairs.find (key);
if (result != _Pairs.end())
{
value = atof (result->second.c_str());
return true;
}
else
return false;
}
int CfgParser::get (const std::string& key, int defaultValue)
{
int value;
if (getInteger (key, value) == false)
return defaultValue;
else
return value;
}
bool CfgParser::getInteger (const std::string& key, int& value)
{
std::map<std::string, std::string>::const_iterator result;
result = _Pairs.find (key);
if (result != _Pairs.end())
{
value = atoi (result->second.c_str());
return true;
}
else
return false;
}
bool CfgParser::get (const std::string& key, bool defaultValue)
{
bool value;
if (getBoolean (key, value) == false)
return defaultValue;
else
return value;
}
bool CfgParser::getBoolean (const std::string& key, bool& value)
{
std::map<std::string, std::string>::const_iterator result;
result = _Pairs.find (key);
if (result != _Pairs.end())
{
value = false;
if (result->second == "true")
value = true;
else if (result->second == "1")
value = true;
else if (result->second == "yes")
value = true;
return true;
}
else
return false;
}
std::string CfgParser::get (const std::string& key, std::string defaultValue)
{
std::string value;
if (getString (key, value) == false)
return defaultValue;
else
return value;
}
bool CfgParser::getString (const std::string& key, std::string& value)
{
std::map<std::string, std::string>::const_iterator result;
result = _Pairs.find (key);
if (result != _Pairs.end())
{
value = result->second;
return true;
}
else
return false;
}
bool CfgParser::getStrings (const std::string& key, std::vector<string>& strings)
{
std::map<std::string, std::string>::const_iterator result;
result = _Pairs.find (key);
if (result != _Pairs.end())
{
explode (result->second, strings, true, ",");
return true;
}
else
return false;
}
} // namespace BlueCore

View File

@ -0,0 +1,39 @@
#ifndef BLUECORE_UTILITIES_CFGPARSER
#define BLUECORE_UTILITIES_CFGPARSER
#include <string>
#include <map>
#include <vector>
namespace BlueCore {
class CfgParser
{
public:
void parseFile (const std::string& filename);
void parseLine (const std::string& line);
void parse (const char* buffer, unsigned int length);
double get (const std::string& key, double value = 0.0);
bool getDouble (const std::string& key, double& defaultValue);
int get (const std::string& key, int value = 0);
bool getInteger (const std::string& key, int& defaultValue);
bool get (const std::string& key, bool value = false);
bool getBoolean (const std::string& key, bool& defaultValue);
std::string get (const std::string& key, std::string value = "");
bool getString (const std::string& key, std::string& defaultValue);
bool getStrings (const std::string& key, std::vector<std::string>& strings);
private:
std::map<std::string, std::string> _Pairs;
};
} // namespace BlueCore
#endif

View File

@ -0,0 +1,11 @@
#include <string>
#include <map>
class IniParser
{
std::map<std::string, std::string> _Pairs;
void parse (const std::string &text)
{
}
}

View File

@ -0,0 +1,82 @@
#include "Kernel.h"
namespace BlueCore
{
Kernel::Kernel() :
_Changed(true), _Clear(false)
{
}
void Kernel::addTask(KernelTask* task, int priority)
{
_AddedTasks.push_back(KernelTaskContainer (task, priority));
_Changed = true;
}
void Kernel::removeTask(KernelTask* task)
{
_RemovedTasks.push_back(task );
_Changed = true;
}
void Kernel::removeAllTasks()
{
_Clear = true;
}
void Kernel::setTaskPriority(KernelTask* task, int priority)
{
std::list<KernelTaskContainer>::iterator i;
for (i = _Tasks.begin(); i != _Tasks.end(); i++)
{
if ((*i)._Task.get() == task)
{
(*i)._Priority = priority;
_Changed = true;
return;
}
}
}
bool Kernel::tick()
{
if (_Changed)
{
std::list<KernelTaskContainer>::iterator i;
for (i = _AddedTasks.begin(); i != _AddedTasks.end(); i++)
{
_Tasks.push_back( *i );
}
_AddedTasks.clear();
_RemovedTasks.clear();
_Tasks.sort();
_Changed = false;
}
std::list<KernelTaskContainer>::iterator i = _Tasks.begin();
std::list<KernelTaskContainer>::iterator end = _Tasks.end();
if (i == end)
return false;
while (i != end)
{
if ((*i)._Task.valid())
(*i)._Task->tick();
i++;
}
if (_Clear)
{
_Tasks.clear();
_Clear = false;
}
return true;
}
} // namespace BlueCore

83
engine/Utilities/Kernel.h Normal file
View File

@ -0,0 +1,83 @@
#ifndef KERNEL_H_
#define KERNEL_H_
#include "Referenced.h"
#include <vector>
#include <iostream>
#include <exception>
#include <list>
namespace BlueCore
{
class Kernel;
//-----------------------------------------------------------------------------
class KernelTask : public Referenced
{
protected:
~KernelTask()
{
}
public:
KernelTask()
{
}
virtual void tick()
{
}
};
//-----------------------------------------------------------------------------
class Kernel : public Referenced
{
private:
struct KernelTaskContainer
{
ref_ptr<KernelTask> _Task;
int _Priority;
KernelTaskContainer(KernelTask* task, int priority) :
_Task(task), _Priority(priority)
{
}
bool operator <(const KernelTaskContainer& other) const
{
return (_Priority > other._Priority);
}
};
std::list<KernelTaskContainer> _Tasks;
std::list<KernelTaskContainer> _AddedTasks;
std::list<KernelTask*> _RemovedTasks;
bool _Changed;
bool _Clear;
protected:
~Kernel()
{
}
public:
Kernel();
void addTask(KernelTask* task, int priority);
void removeTask(KernelTask* task);
void removeAllTasks();
void setTaskPriority(KernelTask* task, int priority);
bool tick();
};
} // namespace BlueCore
#endif /*KERNEL_H_*/

75
engine/Utilities/Log.cpp Normal file
View File

@ -0,0 +1,75 @@
#include "Log.h"
#include <ctime>
namespace BlueCore
{
//--------------------------------------------------------------------------
Log::Log() :
_LogFilename( "log.txt" )
{
reset();
}
//--------------------------------------------------------------------------
void Log::reset()
{
std::ifstream testfile( _LogFilename.c_str() );
if( testfile.is_open() )
{
testfile.close();
_LogFile.open( _LogFilename.c_str(), std::ios::trunc );
_LogFile.close();
}
}
//--------------------------------------------------------------------------
void Log::setFilename( const std::string &name )
{
_LogFilename = name;
reset();
}
//--------------------------------------------------------------------------
Log &Log::operator << (const EndLine &e)
{
_LogFile << '\n';
std::cout << '\n';
return *this;
}
//--------------------------------------------------------------------------
Log &Log::operator << (const EndLog &e)
{
_LogFile << '\n';
_LogFile.close();
std::cout << '\n';
std::cout.flush();
return *this;
}
//--------------------------------------------------------------------------
Log &Log::operator << (const Time &t)
{
std::time_t rawtime;
std::time ( &rawtime );
char *tc = std::ctime( &rawtime );
_LogFile << tc;
std::cout << tc;
return *this;
}
//--------------------------------------------------------------------------
Log &Log::operator << (const Flush &f)
{
_LogFile.close();
std::cout.flush();
return *this;
}
//--------------------------------------------------------------------------
Log::EndLine endline;
Log::EndLog endlog;
Log::Time time;
Log::Flush flush;
Log clog;
}

60
engine/Utilities/Log.h Normal file
View File

@ -0,0 +1,60 @@
#ifndef BLUECORE_LOG_H
#define BLUECORE_LOG_H
#include <iostream>
#include <fstream>
namespace BlueCore
{
class Log
{
std::string _LogFilename;
std::ofstream _LogFile;
public:
class EndLine
{
};
class EndLog
{
};
class Time
{
};
class Flush
{
};
Log();
void setFilename( const std::string &name );
void reset();
template<class T>
Log &operator << (const T &v)
{
if( !_LogFile.is_open() )
_LogFile.open(_LogFilename.c_str(), std::ios::app);
_LogFile << v;
std::cout << v;
return *this;
}
Log &operator << (const EndLine &e);
Log &operator << (const EndLog &e);
Log &operator << (const Time &t);
Log &operator << (const Flush &f);
};
extern Log::EndLine endline;
extern Log::EndLog endlog;
extern Log::Time time;
extern Log::Flush flush;
extern Log clog;
} // namespace bc
#endif // BLUECORE_LOG_H

View File

@ -0,0 +1,423 @@
// 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.0 15 May 2003 rjwagner@writeme.com
// 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.keio.ac.jp/~matumoto/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 - 2003, 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: matumoto@math.keio.ac.jp
// with an appropriate reference to your work.
//
// It would be nice to CC: rjwagner@writeme.com and Cokus@math.washington.edu
// when you write.
#ifndef MERSENNETWISTER_H
#define MERSENNETWISTER_H
// Not thread safe (unless auto-initialization is avoided and each thread has
// its own MTRand object)
#include <iostream>
#include <limits.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
class MTRand {
// Data
public:
typedef unsigned long uint32; // unsigned integer type, at least 32 bits
enum { N = 624 }; // length of state vector
enum { SAVE = N + 1 }; // length of array for save()
protected:
enum { M = 397 }; // period parameter
uint32 state[N]; // internal state
uint32 *pNext; // next value to get from state
int left; // number of values left before reload needed
//Methods
public:
MTRand( const uint32& oneSeed ); // initialize with a simple uint32
MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or an array
MTRand(); // auto-initialize with /dev/urandom or time() and clock()
// Do NOT use for CRYPTOGRAPHY without securely hashing several returned
// values together, otherwise the generator state can be learned after
// reading 624 consecutive values.
// Access to 32-bit random numbers
double rand(); // real number in [0,1]
double rand( const double& n ); // real number in [0,n]
double randExc(); // real number in [0,1)
double randExc( const double& n ); // real number in [0,n)
double randDblExc(); // real number in (0,1)
double randDblExc( const double& n ); // real number in (0,n)
uint32 randInt(); // integer in [0,2^32-1]
uint32 randInt( const uint32& n ); // integer in [0,n] for n < 2^32
double operator()() { return rand(); } // same as rand()
// Access to 53-bit random numbers (capacity of IEEE double precision)
double rand53(); // real number in [0,1)
// Access to nonuniform random number distributions
double randNorm( const double& mean = 0.0, const double& variance = 0.0 );
// Re-seeding functions with same behavior as initializers
void seed( const uint32 oneSeed );
void seed( uint32 *const bigSeed, const uint32 seedLength = N );
void seed();
// Saving and loading generator state
void save( uint32* saveArray ) const; // to array of size SAVE
void load( uint32 *const loadArray ); // from such array
friend std::ostream& operator<<( std::ostream& os, const MTRand& mtrand );
friend std::istream& operator>>( std::istream& is, MTRand& mtrand );
protected:
void initialize( const uint32 oneSeed );
void reload();
uint32 hiBit( const uint32& u ) const { return u & 0x80000000UL; }
uint32 loBit( const uint32& u ) const { return u & 0x00000001UL; }
uint32 loBits( const uint32& u ) const { return u & 0x7fffffffUL; }
uint32 mixBits( const uint32& u, const uint32& v ) const
{ return hiBit(u) | loBits(v); }
uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const
{ return m ^ (mixBits(s0,s1)>>1) ^ (-loBit(s1) & 0x9908b0dfUL); }
static uint32 hash( time_t t, clock_t c );
};
inline MTRand::MTRand( const uint32& oneSeed )
{ seed(oneSeed); }
inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength )
{ seed(bigSeed,seedLength); }
inline MTRand::MTRand()
{ seed(); }
inline double MTRand::rand()
{ return double(randInt()) * (1.0/4294967295.0); }
inline double MTRand::rand( const double& n )
{ return rand() * n; }
inline double MTRand::randExc()
{ return double(randInt()) * (1.0/4294967296.0); }
inline double MTRand::randExc( const double& n )
{ return randExc() * n; }
inline double MTRand::randDblExc()
{ return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
inline double MTRand::randDblExc( const double& n )
{ return randDblExc() * n; }
inline double MTRand::rand53()
{
uint32 a = randInt() >> 5, b = randInt() >> 6;
return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0); // by Isaku Wada
}
inline double MTRand::randNorm( const double& mean, const double& variance )
{
// Return a real number from a normal (Gaussian) distribution with given
// mean and variance by Box-Muller method
double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance;
double phi = 2.0 * 3.14159265358979323846264338328 * randExc();
return mean + r * cos(phi);
}
inline MTRand::uint32 MTRand::randInt()
{
// Pull a 32-bit integer from the generator state
// Every other access function simply transforms the numbers extracted here
if( left == 0 ) reload();
--left;
register uint32 s1;
s1 = *pNext++;
s1 ^= (s1 >> 11);
s1 ^= (s1 << 7) & 0x9d2c5680UL;
s1 ^= (s1 << 15) & 0xefc60000UL;
return ( s1 ^ (s1 >> 18) );
}
inline MTRand::uint32 MTRand::randInt( const uint32& n )
{
// Find which bits are used in n
// Optimized by Magnus Jonsson (magnus@smartelectronix.com)
uint32 used = n;
used |= used >> 1;
used |= used >> 2;
used |= used >> 4;
used |= used >> 8;
used |= used >> 16;
// Draw numbers until one is found in [0,n]
uint32 i;
do
i = randInt() & used; // toss unused bits to shorten search
while( i > n );
return i;
}
inline void MTRand::seed( const uint32 oneSeed )
{
// Seed the generator with a simple uint32
initialize(oneSeed);
reload();
}
inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength )
{
// Seed the generator with an array of uint32's
// There are 2^19937-1 possible initial states. This function allows
// all of those to be accessed by providing at least 19937 bits (with a
// default seed length of N = 624 uint32's). Any bits above the lower 32
// in each element are discarded.
// Just call seed() if you want to get array from /dev/urandom
initialize(19650218UL);
register int i = 1;
register uint32 j = 0;
register int k = ( N > seedLength ? N : seedLength );
for( ; k; --k )
{
state[i] =
state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL );
state[i] += ( bigSeed[j] & 0xffffffffUL ) + j;
state[i] &= 0xffffffffUL;
++i; ++j;
if( i >= N ) { state[0] = state[N-1]; i = 1; }
if( j >= seedLength ) j = 0;
}
for( k = N - 1; k; --k )
{
state[i] =
state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL );
state[i] -= i;
state[i] &= 0xffffffffUL;
++i;
if( i >= N ) { state[0] = state[N-1]; i = 1; }
}
state[0] = 0x80000000UL; // MSB is 1, assuring non-zero initial array
reload();
}
inline void MTRand::seed()
{
// Seed the generator with an array from /dev/urandom if available
// Otherwise use a hash of time() and clock() values
// First try getting an array from /dev/urandom
FILE* urandom = fopen( "/dev/urandom", "rb" );
if( urandom )
{
uint32 bigSeed[N];
register uint32 *s = bigSeed;
register int i = N;
register bool success = true;
while( success && i-- )
success = fread( s++, sizeof(uint32), 1, urandom );
fclose(urandom);
if( success ) { seed( bigSeed, N ); return; }
}
// Was not successful, so use time() and clock() instead
seed( hash( time(NULL), clock() ) );
}
inline void MTRand::initialize( const uint32 seed )
{
// Initialize generator state with seed
// See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.
// In previous versions, most significant bits (MSBs) of the seed affect
// only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto.
register uint32 *s = state;
register uint32 *r = state;
register int i = 1;
*s++ = seed & 0xffffffffUL;
for( ; i < N; ++i )
{
*s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL;
r++;
}
}
inline void MTRand::reload()
{
// Generate N new values in state
// Made clearer and faster by Matthew Bellew (matthew.bellew@home.com)
register uint32 *p = state;
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[M-N], p[0], p[1] );
*p = twist( p[M-N], p[0], state[0] );
left = N, pNext = state;
}
inline MTRand::uint32 MTRand::hash( time_t t, clock_t c )
{
// Get a uint32 from t and c
// Better than uint32(x) in case x is floating point in [0,1]
// Based on code by Lawrence Kirby (fred@genesis.demon.co.uk)
static uint32 differ = 0; // guarantee time-based seeds will change
uint32 h1 = 0;
unsigned char *p = (unsigned char *) &t;
for( size_t i = 0; i < sizeof(t); ++i )
{
h1 *= UCHAR_MAX + 2U;
h1 += p[i];
}
uint32 h2 = 0;
p = (unsigned char *) &c;
for( size_t j = 0; j < sizeof(c); ++j )
{
h2 *= UCHAR_MAX + 2U;
h2 += p[j];
}
return ( h1 + differ++ ) ^ h2;
}
inline void MTRand::save( uint32* saveArray ) const
{
register uint32 *sa = saveArray;
register const uint32 *s = state;
register int i = N;
for( ; i--; *sa++ = *s++ ) {}
*sa = left;
}
inline void MTRand::load( uint32 *const loadArray )
{
register uint32 *s = state;
register uint32 *la = loadArray;
register int i = N;
for( ; i--; *s++ = *la++ ) {}
left = *la;
pNext = &state[N-left];
}
inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand )
{
register const MTRand::uint32 *s = mtrand.state;
register int i = mtrand.N;
for( ; i--; os << *s++ << "\t" ) {}
return os << mtrand.left;
}
inline std::istream& operator>>( std::istream& is, MTRand& mtrand )
{
register MTRand::uint32 *s = mtrand.state;
register int i = mtrand.N;
for( ; i--; is >> *s++ ) {}
is >> mtrand.left;
mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left];
return is;
}
#endif // MERSENNETWISTER_H
// Change log:
//
// v0.1 - First release on 15 May 2000
// - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
// - Translated from C to C++
// - Made completely ANSI compliant
// - Designed convenient interface for initialization, seeding, and
// obtaining numbers in default or user-defined ranges
// - Added automatic seeding from /dev/urandom or time() and clock()
// - Provided functions for saving and loading generator state
//
// v0.2 - Fixed bug which reloaded generator one step too late
//
// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew
//
// v0.4 - Removed trailing newline in saved generator format to be consistent
// with output format of built-in types
//
// v0.5 - Improved portability by replacing static const int's with enum's and
// clarifying return values in seed(); suggested by Eric Heimburg
// - Removed MAXINT constant; use 0xffffffffUL instead
//
// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits
// - Changed integer [0,n] generator to give better uniformity
//
// v0.7 - Fixed operator precedence ambiguity in reload()
// - Added access for real numbers in (0,1) and (0,n)
//
// v0.8 - Included time.h header to properly support time_t and clock_t
//
// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto
// - Allowed for seeding with arrays of any length
// - Added access for real numbers in [0,1) with 53-bit resolution
// - Added access for real numbers from normal (Gaussian) distributions
// - Increased overall speed by optimizing twist()
// - Doubled speed of integer [0,n] generation
// - Fixed out-of-range number generation on 64-bit machines
// - Improved portability by substituting literal constants for long enum's
// - Changed license from GNU LGPL to BSD

64
engine/Utilities/Named.h Normal file
View File

@ -0,0 +1,64 @@
#ifndef BLUECORE_NAMED_H
#define BLUECORE_NAMED_H
#include <string>
namespace BlueCore
{
class Named
{
private:
std::string _Name;
public:
/**
* Default constructor.
*/
inline Named() :
_Name( "" )
{
}
/**
* Constructor.
* @param strName set initial name
*/
inline Named( const std::string &name ) :
_Name( name )
{
}
/**
* Destructor.
*/
virtual inline ~Named()
{
}
/**
* Get the name.
* @return returns the name
*/
inline const std::string &getName() const
{
return _Name;
}
/**
* Set the name.
*/
inline void setName( const std::string &name )
{
_Name = name;
}
};
}
#endif

View File

@ -0,0 +1,236 @@
#ifndef BLUECORE_REFERENCED_COUNTER_H
#define BLUECORE_REFERENCED_COUNTER_H
#include <list>
namespace BlueCore
{
class Referenced
{
public:
class DestructionListener
{
public:
virtual void onDestruction(Referenced *referenced) = 0;
};
private:
std::list<DestructionListener*> _DestructionListeners;
unsigned int _ReferenceCount;
virtual void destroyReferenced()
{
while (_DestructionListeners.begin() != _DestructionListeners.end())
{
if (_DestructionListeners.front() != 0)
_DestructionListeners.front()->onDestruction(this);
_DestructionListeners.pop_front();
}
delete this;
}
public:
inline Referenced() :
_ReferenceCount(0)
{
}
virtual inline ~Referenced()
{
}
inline void addReference()
{
_ReferenceCount += 1;
}
inline void removeReference()
{
if (_ReferenceCount > 0)
{
_ReferenceCount -= 1;
if ( 0 == _ReferenceCount)
{
destroyReferenced();
}
}
}
inline unsigned int getReferenceCount()
{
return _ReferenceCount;
}
inline void addDestructionListener(DestructionListener *listener)
{
if (listener != 0)
_DestructionListeners.push_back(listener);
}
inline void removeDestructionListener(DestructionListener *listener)
{
_DestructionListeners.remove(listener);
}
};
template<class T> class ref_ptr
{
public:
ref_ptr() :
_Referenced(0)
{
}
ref_ptr(T* referenced) :
_Referenced(referenced)
{
if (_Referenced)
_Referenced->addReference();
}
ref_ptr(const ref_ptr& op) :
_Referenced(op._Referenced)
{
if (_Referenced)
_Referenced->addReference();
}
~ref_ptr()
{
if (_Referenced)
_Referenced->removeReference();
}
T* operator ->() const
{
return _Referenced;
}
ref_ptr& operator =(T* op)
{
if (op != _Referenced)
{
if (_Referenced != 0)
_Referenced->removeReference();
_Referenced = op;
if (_Referenced)
_Referenced->addReference();
}
return *this;
}
bool operator ==(const ref_ptr& ref)
{
if (_Referenced == ref._Referenced)
return true;
else
return false;
}
bool valid() const
{
return (_Referenced != 0);
}
operator T*() const
{
return _Referenced;
}
T* get() const
{
return _Referenced;
}
private:
T* _Referenced;
};
template<class T> class weak_ptr : public Referenced::DestructionListener
{
public:
weak_ptr() :
_Referenced(0)
{
}
weak_ptr(T* referenced) :
_Referenced(referenced)
{
if (_Referenced)
_Referenced->addDestructionListener(this);
}
weak_ptr(const weak_ptr& op) :
_Referenced(op._Referenced)
{
if (_Referenced)
_Referenced->addDestructionListener(this);
}
virtual ~weak_ptr()
{
if (_Referenced)
_Referenced->removeDestructionListener(this);
}
T* operator ->() const
{
return _Referenced;
}
weak_ptr& operator =(T* op)
{
if (op != _Referenced && _Referenced != 0)
_Referenced->removeDestructionListener(this);
_Referenced = op;
_Referenced->addDestructionListener(this);
return *this;
}
bool operator ==(const weak_ptr& ref)
{
if (_Referenced == ref._Referenced)
return true;
else
return false;
}
bool valid() const
{
return (_Referenced != 0);
}
T* get() const
{
return _Referenced;
}
void onDestruction(Referenced *referenced)
{
_Referenced = 0;
}
private:
T* _Referenced;
};
} // namespace BlueCore
#endif

View File

@ -0,0 +1,119 @@
#ifndef BLUECORE_STRING_UTILITIES_H
#define BLUECORE_STRING_UTILITIES_H
#include <iostream>
#include <string>
#include <vector>
namespace BlueCore {
#define SPACES " \t\r\n"
/**
* Function to remove whitespaces from the end of the string.
* @param s String to be trimmed.
* @param t String containing whitespaces. Default: space, tab, carriage return and newline.
*/
inline std::string trim_right(
const std::string &s,
const std::string &t = SPACES )
{
std::string::size_type i (s.find_last_not_of (t));
if (i == std::string::npos)
return "";
else
return std::string( s, 0, i );
}
/**
* Function to remove whitespaces from the beginning of the string.
* @param s String to be trimmed.
* @param t String containing whitespaces. Default: space, tab, carriage return and newline.
*/
inline std::string trim_left(
const std::string &s,
const std::string &t = SPACES )
{
return std::string( s, s.find_first_not_of(t) );
}
/**
* Function to remove whitespaces from the beginning and the end of the string.
* @param s String to be trimmed.
* @param t String containing whitespaces. Default: space, tab, carriage return and newline.
*/
inline std::string trim(
const std::string &s,
const std::string &t = SPACES )
{
std::string::size_type a = s.find_first_not_of(t), b = s.find_last_not_of(t);
if ( a == std::string::npos || b == std::string::npos )
return "";
return std::string( s, a, b-a+1 );
}
/**
* Splits a string into pieces, and returns them in an array.
* @param s String to be exploded.
* @param v Vector which receives the pieces.
* @param t String containing whitespaces. Default: space, tab, carriage return and newline.
* @param trim_spaces Flag to decide if pieces should be trimmed. Default: false.
*/
inline void explode(
const std::string &s,
std::vector<std::string> &v,
const bool trim_spaces = false,
const std::string &t = SPACES )
{
std::string::size_type a, b;
a = s.find_first_not_of(t), b = s.find_first_of(t, a);
while( a != std::string::npos )
{
if( trim_spaces )
v.push_back( trim( s.substr(a, b-a) ) );
else
v.push_back( s.substr(a, b-a) );
a = s.find_first_not_of(t, b), b = s.find_first_of(t, a);
}
}
/**
* Function to assemble strings from a vector into one strng.
* @param v Vector which conatins the string pieces.
* @param t String which is places between peaces. Default: one space " ".
* @return Assembled string.
*/
inline std::string implode(
const std::vector<std::string> &v,
const std::string &t = " " )
{
unsigned int i;
std::string s;
for( i = 0; i < (v.size() - 1); i++)
{
s.append( v[i] );
s.append( t );
}
return s+v[i];
}
} // namespace BlueCore
#endif

142
engine/Utilities/format.cpp Normal file
View File

@ -0,0 +1,142 @@
#include "format.h"
#ifndef NFORMAT
void Format::CFormat::reset()
{
valid = false;
adjust = RIGHT;
special = false;
precision = 6;
precision_explicit = false;
zero = false;
sign = false;
width = 0;
internal = false;
setupper = false;
grouping = false;
conversion = false;
base = DEC;
floating = FIXED;
showbase = false;
strlength = 0;
}
int Format::skip_atoi( std::string s, ST start, ST& pos )
{
pos = start;
ST len = s.size();
while( (pos < len) && isdigit( s[pos] ) )
pos++;
return atoi( s.substr( start, start-pos ).c_str() );
}
void Format::CFormat::set( std::ostream& out )
{
if( !valid )
{
return;
}
/*
printf( "valid: %d\n", valid );
printf( "adjust: %d\n", adjust );
printf( "special: %d\n", special );
printf( "precision: %d\n", precision );
printf( "precision_explicit: %d\n", precision_explicit );
printf( "zero: %d\n", zero );
printf( "sign: %d\n", sign );
printf( "width: %d\n", width );
printf( "internal: %d\n", internal );
printf( "setupper: %d\n", setupper );
printf( "grouping: %d\n", grouping );
printf( "conversion: %d\n", conversion );
printf( "base: %d\n", base );
printf( "floating: %d\n", floating );
printf( "showbase: %d\n", showbase );
printf( "strlength: %d\n", strlength );
*/
if( base == HEX && special && showbase && zero )
{
// without this correction:
// printf( "[%#08x]", 0x42 ) => [0x000042]
// fromat( "[%#08x]", 0x42 ) => [00000x42]
showbase = false;
out << '0' << ( setupper ? 'X' : 'x' );
width -= 2;
}
if( base == HEX && special && showbase && strlength )
{
/*
sprintf( buffer, "[%#8.3x]", 0x42 ) => [ 0x042]
*/
showbase = false;
if( width )
{
for( int i = 0; i + strlength + 2 + 1 < width; ++i )
out << ' ';
width = 0;
}
out << '0' << ( setupper ? 'X' : 'x' );
for( int i = 0; i + strlength < precision; ++i )
out << '0';
}
if( adjust == LEFT && zero )
{
/*
sprintf( buffer, "[%-#08x]", 0x42 ); => [0x42 ]
not => [0x420000]
*/
zero = false;
}
switch( adjust )
{
case LEFT: out.setf( std::ios::left, std::ios::adjustfield ); break;
case RIGHT: out.setf( std::ios::right, std::ios::adjustfield ); break;
}
if( zero ) out << std::setfill('0');
else out << std::setfill( ' ' );
if( sign ) out.setf( std::ios::showpos );
else out.unsetf( std::ios::showpos );
if( internal )
out.setf( std::ios::internal, std::ios::adjustfield );
switch( base )
{
case OCT: out.setf( std::ios::oct, std::ios::basefield ); break;
case DEC: out.setf( std::ios::dec, std::ios::basefield ); break;
case HEX: out.setf( std::ios::hex, std::ios::basefield ); break;
}
if( setupper ) out.setf( std::ios::uppercase );
else out.unsetf( std::ios::uppercase );
switch( floating )
{
case FIXED: out.setf( std::ios::fixed, std::ios::floatfield ); break;
case SCIENTIFIC: out.setf( std::ios::scientific, std::ios::floatfield ); break;
}
if( showbase )
out.setf( std::ios::showbase );
else
out.unsetf( std::ios::showbase );
out << std::setw( width );
out << std::setprecision( precision );
}
#endif

919
engine/Utilities/format.h Normal file
View File

@ -0,0 +1,919 @@
/*
Format a C++ library for typesafe string formating in printf style
(C) 2001 - 2003 by Martin Oberzalek <kingleo@gmx.at>
Examples:
std::cout << format( "Hello %s, I have $05d$ in my pocket", "world", 5 ) << std::endl;
std::cout << format( "Do not try this with printf: %s", 10101 ) << std::endl;
*/
#ifndef format_h
#define format_h
#include <string>
#include <iomanip>
#include <iostream>
/**
Can we use stringstreams or do we have to use the deprecated strstreams instead?
If we have to use strstreams, simple comment the next #define
**/
#define HAVE_STL_SSTREAM
#define NFORMAT
#if __GNUC__ == 2
#undef HAVE_STL_SSTREAM
#endif
#ifdef HAVE_STL_SSTREAM
# include <sstream>
# include <cctype>
# define IS_DIGIT( x ) std::isdigit( x )
#else
extern "C" {
# include <ctype.h>
}
# include <strstream>
# define IS_DIGIT( x ) isdigit( x )
#endif
#ifndef NFORMAT
namespace Format
{
typedef std::string::size_type ST;
class CFormat
{
public:
typedef enum Adjust
{
LEFT,
RIGHT
};
typedef enum Base
{
OCT,
DEC,
HEX
};
typedef enum Floating
{
FIXED,
SCIENTIFIC
};
bool valid;
Adjust adjust;
bool special;
bool sign;
bool grouping; // SUSv2 extension
bool conversion; // glibc 2.2 extension
bool zero;
bool precision_explicit;
bool internal;
Base base;
bool setupper;
Floating floating;
bool showbase;
int width;
int precision;
int strlength;
std::string format;
public:
CFormat() { reset(); }
void set( std::ostream& out );
private:
void reset();
};
/****************************************/
// all the errors that are thrown
// are a cause of a mistake with %* or %*m$
class Error
{
public:
std::string err;
Error( std::string s ) : err( s ) {}
};
/****************************************/
template <class A, class B, class C, class D, class E, class F>
class Format
{
private:
struct Arg
{
bool is_int;
bool is_string;
};
Arg args[6];
std::string format;
A a;
B b;
C c;
D d;
E e;
F f;
unsigned int num_of_args;
std::string s;
public:
Format( const std::string &format, A a, B b, C c, D d, E e, F f, unsigned int num_of_args );
std::string get_string() const { return s; }
private:
void parse();
template <class N> bool is_int( N &n ) { return false; }
bool is_int( int &n ) { return true; }
bool is_int( unsigned int &n ) { return true; }
bool is_int( short &n ) { return true; }
bool is_int( unsigned short ) { return true; }
template <class S> bool is_string( S &s ) { return false; }
bool is_string( std::string& s ) { return true; }
bool is_string( const std::string& s ) { return true; }
bool is_string( char* ) { return true; }
bool is_string( const char* ) { return true; }
int get_int_arg( unsigned int num );
void gen_arg_list();
std::string use_arg( unsigned int i, const CFormat &cf );
template <class S> std::string x2s( S ss, const CFormat &cf )
{
#ifdef HAVE_STL_SSTREAM
std::stringstream str;
str << cf << ss;
std::string st = str.str();
return st;
#else
std::strstream str;
str << cf << ss << std::ends;
std::string st = str.str();
str.freeze(0);
return st;
#endif
}
};
int skip_atoi( std::string s, ST start, ST& pos );
} // namespace Format
inline std::ostream& operator<<( std::ostream& out, Format::CFormat cf )
{
cf.set( out );
return out;
}
template <class A, class B, class C, class D, class E, class F>
Format::Format<A,B,C,D,E,F>::Format( std::string const &format, A a, B b, C c, D d, E e, F f, unsigned int num_of_args )
: format( format ), a(a), b(b), c(c), d(d), e(e), f(f), num_of_args( num_of_args )
{
if( num_of_args > 6 )
throw Error( "Number of args out of range" );
gen_arg_list();
parse();
}
template <class A, class B, class C, class D, class E, class F>
int Format::Format<A,B,C,D,E,F>::get_int_arg( unsigned int num )
{
if( static_cast<unsigned int>(num) > num_of_args - 1 )
throw Error( "The arg you wan't to use is out of range" );
if( num < 0 )
throw Error( "negativ number for arg number not allowed" );
if( args[num].is_int )
{
switch( num )
{
case 0: return *((int*) &a); // I have to cast here cause the compiler
case 1: return *((int*) &b); // will make troubles if any of these
case 2: return *((int*) &c); // values is not an unsigned int.
case 3: return *((int*) &d); // Even if we are sure that
case 4: return *((int*) &e); // an unsigned int value will be returned
case 5: return *((int*) &f);
}
}
else
throw Error( "expecting int arg" );
return 0; // should never be reached
}
template <class A, class B, class C, class D, class E, class F>
void Format::Format<A,B,C,D,E,F>::gen_arg_list()
{
for( unsigned int i = 0; i < num_of_args; i++ )
{
switch( i )
{
case 0:
args[i].is_int = is_int( a );
args[i].is_string = is_string( a );
break;
case 1:
args[i].is_int = is_int( b );
args[i].is_string = is_string( b );
break;
case 2:
args[i].is_int = is_int( c );
args[i].is_string = is_string( c );
break;
case 3:
args[i].is_int = is_int( d );
args[i].is_string = is_string( d );
break;
case 4:
args[i].is_int = is_int( e );
args[i].is_string = is_string( e );
break;
case 5:
args[i].is_int = is_int( f );
args[i].is_string = is_string( f );
break;
}
}
}
template <class A, class B, class C, class D, class E, class F>
std::string Format::Format<A,B,C,D,E,F>::use_arg( unsigned int i, const CFormat &cf )
{
if( i > num_of_args || i < 0 )
throw Error( "out of arg range" );
switch( i )
{
case 0: return x2s( a, cf );
case 1: return x2s( b, cf );
case 2: return x2s( c, cf );
case 3: return x2s( d, cf );
case 4: return x2s( e, cf );
case 5: return x2s( f, cf );
}
return "";
}
template <class A, class B, class C, class D, class E, class F>
void Format::Format<A,B,C,D,E,F>::parse()
{
if( format.empty() )
return;
unsigned int par = 0;
unsigned int use_par = 0;
ST pos = 0;
ST len = format.size();
s = "";
bool had_precision = false;
while( par < num_of_args && pos < len )
{ // while
use_par = par;
if( pos >= len )
break;
if( format[pos] != '%' )
{
s += format[pos];
pos++;
continue;
}
// % digit found
pos++;
if( !(pos < len ) || (format[pos] == '%') )
{
// %% -> %
s += format[pos];
pos++;
continue;
}
// format string found
ST start = pos - 1;
CFormat f;
// process flags
while( (pos < len) )
{
bool finished = false;
switch( format[pos] )
{
case '-' : f.adjust = CFormat::LEFT; break;
case '+' : f.sign = true; break;
case ' ' : f.zero = false; break;
case '#' : f.special = true; break;
case '\'': f.grouping = true; break;
case 'I' : f.conversion = true; break;
case '0' : f.zero = true; break;
default: finished = true; break;
}
if( finished )
break;
pos++;
} // while( (pos < len) )
// get argument number
if( pos < len )
{
// search for the $ digit
unsigned int dp = pos;
while( dp < len && IS_DIGIT( format[dp] ) )
dp++;
if( dp < len && format[dp] == '$' )
{
use_par = skip_atoi( format, pos, pos ) - 1;
pos = dp + 1;
}
}
// get field with
if( pos < len )
{
if( IS_DIGIT( format[pos] ) )
f.width = skip_atoi( format, pos, pos );
else if( format[pos] == '*' )
{
pos++;
// search for the $ digit
unsigned int dp = pos;
while( dp < len && IS_DIGIT( format[dp] ) )
dp++;
if( dp < len && format[dp] == '$' )
{
f.width = get_int_arg( skip_atoi( format, pos, pos ) - 1 );
// skip $ sign
pos++;
}
else
{
f.width = get_int_arg( par );
if( use_par == par )
use_par++;
par++;
}
if( f.width < 0 )
{
f.width *= -1;
f.adjust = CFormat::LEFT;
}
}
}
// precision
if( pos < len )
{
if( format[pos] == '.' )
{
pos++;
if( !(pos < len) )
return;
had_precision = true;
if( IS_DIGIT( format[pos] ) )
f.precision = skip_atoi( format, pos, pos );
else if( format[pos] == '*' )
{
pos++;
// search for the $ digit
unsigned int dp = pos;
while( dp < len && IS_DIGIT( format[dp] ) )
dp++;
if( dp < len && format[dp] == '$' )
{
f.precision = get_int_arg( skip_atoi( format, pos, pos ) - 1 );
// skip $ sign
pos++;
}
else
{
f.precision = get_int_arg( par );
if( use_par == par )
use_par++;
par++;
}
if( f.precision == 0)
f.precision_explicit = true;
if( f.precision < 0 )
f.precision = 0;
}
else
f.precision = 0;
}
}
// lenght modifier
/*
they will be ignored
cause we know the types of the parameter
*/
if( (pos < len) )
{
bool hh = false;
bool ll = false;
bool found = false;
switch( format[pos] )
{
case 'h': hh = true; found = true; break;
case 'l': ll = true; found = true; break;
case 'L':
case 'q':
case 'j':
case 'z':
case 't': found = true; break;
default: break;
}
if(found )
{
pos++;
if( pos < len )
if( hh == true )
{
if( format[pos] == 'h' )
pos++;
}
else if( ll = true )
if( format[pos] == 'l' )
pos++;
}
}
// conversion specifier
if( pos < len )
{
bool invalid = false;
switch( format[pos] )
{
case 'd':
case 'i':
f.base = CFormat::DEC;
if( f.zero && (f.adjust != CFormat::LEFT) )
f.internal = true;
break;
case 'X': f.setupper = true;
case 'x':
f.base = CFormat::HEX;
if( f.special )
f.showbase = true;
break;
case 'o':
f.base = CFormat::OCT;
if( f.special )
f.showbase = true;
break;
case 'E':
f.setupper = true;
case 'e':
if( f.special )
f.sign = true;
f.floating = CFormat::SCIENTIFIC;
break;
case 'F': // not supported
case 'f':
if( f.special )
f.sign = true;
f.floating = CFormat::FIXED;
break;
case 's':
if( f.zero )
f.zero = false;
break;
// unsupported modifiers
case 'G':
case 'g':
case 'A':
case 'a':
case 'c':
case 'C':
case 'S':
case 'P':
case 'n': break;
default: invalid = true;
}
if( !invalid )
f.valid = true;
}
if( f.valid )
{
std::string str;
int upar = par;
if( use_par != par )
upar = use_par;
if( f.base == CFormat::HEX && had_precision && f.special )
{
CFormat f2;
f2.base = f.base;
std::string s = use_arg( upar, f2 );
f.strlength = s.size();
// printf( "str: %s\n", s.c_str() );
}
str = use_arg( upar, f );
// cut string
if( had_precision && args[upar].is_string )
str = str.substr( 0, f.precision );
s += str;
if( use_par == par )
par++;
}
else
{
// copy the invalid format string
for( ST i = start; i<= pos; i++ )
if( i < len )
s += format[i];
}
pos++;
} // while
if( pos < len )
{
while( pos < len )
{
s += format[pos];
pos++;
}
}
}
#else // ifndef NFORMAT
/// converts anything to a string
template<class T>std::string x2s( T what )
{
#ifdef HAVE_STL_SSTREAM
std::stringstream str;
str << what;
std::string s( str.str() );
return s;
#else
std::strstream str;
str << what << std::ends;
std::string s( str.str() );
str.freeze(0);
return s;
#endif
}
#include <cstdio>
namespace Format
{
template <class T> const char* convert( T t ) { return x2s( t ).c_str(); }
#define DEF( TYPE ) \
inline TYPE convert( TYPE t ) { return t; }
DEF( unsigned )
DEF( int )
DEF( char )
DEF( char* )
DEF( const char* )
DEF( short )
DEF( double )
DEF( float )
DEF( long )
#undef DEF
template<class A, class B, class C, class D, class E, class F>
class Format
{
std::string s;
public:
Format( const std::string &format, A a, B b, C c, D d, E e, F f, unsigned int num_of_args )
{
#define D( T ) convert( T )
unsigned buffer_size = 256;
bool cont = false;
do {
cont = false;
char *buffer = new char[buffer_size];
int n = 0;
switch( num_of_args )
{
case 1: n = std::sprintf( buffer, format.c_str(),
D( a ) ); break;
case 2: n = std::sprintf( buffer, format.c_str(),
D( a ), D( b ) ); break;
case 3: n = std::sprintf( buffer, format.c_str(),
D( a ), D( b ), D( c ) ); break;
case 4: n = std::sprintf( buffer, format.c_str(),
D( a ), D( b ), D( c ), D( d ) ); break;
case 5: n = std::sprintf( buffer, format.c_str(),
D( a ), D( b ), D( c ), D( d ), D( e ) ); break;
case 6: n = std::sprintf( buffer, format.c_str(),
D( a ), D( b ), D( c ), D( d ), D( e ), D( f ) ); break;
}
if( (unsigned) n >= buffer_size - 2 )
{
buffer_size *= 2;
cont = true;
n = 0;
}
for( int i = 0; i < n; i++ )
s += buffer[i];
delete[] buffer;
} while( cont );
#undef D
}
std::string get_string() const { return s; }
};
}
#endif
template <class A, class B, class C, class D, class E, class F>
inline std::string format( std::string fs, A a, B b, C c, D d, E e, F f )
{
return Format::Format<A,B,C,D,E,F>( fs, a, b, c, d, e, f, 6).get_string();
}
template <class A, class B, class C, class D, class E>
inline std::string format( std::string fs, A a, B b, C c, D d, E e )
{
return Format::Format<A,B,C,D,E,char>( fs, a, b, c, d, e, 0, 5).get_string();
}
template <class A, class B, class C, class D>
inline std::string format( std::string fs, A a, B b, C c, D d)
{
return Format::Format<A,B,C,D,char,char>( fs, a, b, c, d, 0, 0, 4).get_string();
}
template <class A, class B, class C>
inline std::string format( std::string fs, A a, B b, C c )
{
return Format::Format<A,B,C,char,char,char>( fs, a, b, c, 0, 0, 0, 3).get_string();
}
template <class A, class B>
inline std::string format( std::string fs, A a, B b )
{
return Format::Format<A,B,char,char,char,char>( fs, a, b, 0, 0, 0, 0, 2).get_string();
}
template <class A>
inline std::string format( std::string fs, A a)
{
return Format::Format<A,char,char,char,char,char>( fs, a, 0, 0, 0, 0, 0, 1).get_string();
}
namespace Format
{
template<typename ostream> class PrintF
{
private:
int level;
int dlevel;
int dmodule;
int module;
public:
ostream &out;
public:
PrintF( ostream &out = std::cout, int module = -1, int debug_level = -1 )
: level( debug_level ), dlevel( debug_level ),
dmodule( module), module( module), out( out )
{}
void set_debug_level( int dlevel_ ) { dlevel = dlevel_; }
void set_module( int module_ ) { dmodule = module_; }
PrintF operator()( int module_ )
{
PrintF printf( *this );
printf.module = module_;
return printf;
}
PrintF operator[]( int level_ )
{
PrintF printf( *this );
printf.level = level_;
return printf;
}
template<typename T> PrintF& operator<<( const T &t )
{
if( check() )
out << t;
return *this;
}
// io manipulator overloading
PrintF& operator<<(ostream& (*f)(ostream&))
{
if( check() )
out << f;
return *this;
}
PrintF& operator()( std::string fs )
{
if( check() )
out << fs;
return *this;
}
template<typename A> PrintF& operator()( std::string fs, const A &a )
{
if( check() )
out << format( fs, a );
return *this;
}
template<typename A, typename B>
PrintF& operator()( std::string fs, const A &a, const B &b )
{
if( check() )
out << format( fs, a, b );
return *this;
}
template<typename A, typename B, typename C>
PrintF& operator()( std::string fs, const A &a, const B &b, const C &c )
{
if( check() )
out << format( fs, a, b, c );
return *this;
}
template<typename A, typename B, typename C, typename D>
PrintF& operator()( std::string fs, const A &a, const B &b, const C &c, const D &d )
{
if( check() )
out << format( fs, a, b, c, d );
return *this;
}
template<typename A, typename B, typename C, typename D, typename E>
PrintF& operator()( std::string fs, const A &a, const B &b, const C &c, const D &d, const E &e )
{
if( check() )
out << format( fs, a, b, c, d, e );
return *this;
}
template<typename A, typename B, typename C, typename D, typename E, typename F>
PrintF& operator()( std::string fs, const A &a, const B &b, const C &c, const D &d, const E &e, const F &f )
{
if( check() )
out << format( fs, a, b, c, d, e, f );
return *this;
}
bool check( int module, int level ) const
{
if( module == dmodule || dmodule == -1 )
{
if( dlevel == -1 )
return true;
if( level <= dlevel )
return true;
}
return false;
}
private:
bool check() const { return check( module, level ); }
};
}
#undef IS_DIGIT
#endif

2567
engine/Utilities/sigslot.h Normal file

File diff suppressed because it is too large Load Diff