/*
* Infected Engine
*
* Copyright (c) 2013-2014 David Simmerson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
#ifndef _Flag_hpp
#define _Flag_hpp
// **************************************************************
// our flag system, this is used in all sorts of places; and is
// essentialy a god when it comes to bitsetting; (well not really)
// but it is simplistic, which is important.
// this class is virtualized for a reason, we want to inherit this
// class and have direct access to the flag manipulation.
class Flag
{
public:
Flag() {
highestFlag = 0;
}
virtual ~Flag() { }
private:
std::map<int, bool>mFlag;
int highestFlag;
public:
void cleanFlags ( void ) {
std::map<int, bool>::iterator iter, iter_next;
for ( iter = mFlag.begin(); iter != mFlag.end(); iter = iter_next ) {
int x = iter->first;
bool s = iter->second;
iter_next = ++iter;
// strip out our old flag.
if ( !s ) { mFlag.erase ( x ); }
}
}
bool hasFlag ( int flag ) {
std::map<int, bool>::iterator iter, iter_next;
for ( iter = mFlag.begin(); iter != mFlag.end(); iter = iter_next ) {
int x = iter->first;
bool s = iter->second;
iter_next = ++iter;
// could be true or false?
if ( x == flag ) {
return s;
}
}
return false;
}
// toggle the flag on/off!
void toggleFlag ( int flag ) {
std::map<int, bool>::iterator iter, iter_next;
// set the flag
if ( !hasFlag ( flag ) ) {
mFlag[flag] = true;
if ( flag > highestFlag )
{ highestFlag = flag; }
return;
}
// get rid of the flag
for ( iter = mFlag.begin(); iter != mFlag.end(); iter = iter_next ) {
int x = iter->first;
iter_next = ++iter;
if ( x == flag ) {
mFlag.erase ( x );
break;
}
}
}
void setFlag ( int flag, bool value ) {
// removing the flag!
if ( hasFlag ( flag ) && !value ) {
std::map<int, bool>::iterator iter, iter_next;
for ( iter = mFlag.begin(); iter != mFlag.end(); iter = iter_next ) {
int x = iter->first;
iter_next = ++iter;
if ( x == flag ) {
mFlag.erase ( x );
break;
}
}
return;
}
// we don't have it, so we don't set it (save memory)
if ( !value ) { return; }
mFlag[flag] = value;
if ( flag > highestFlag )
{ highestFlag = flag; }
}
std::string flagToString ( void ) {
std::string retStr ( "" );
int x = 0;
while ( x <= highestFlag ) {
char buf[10];
// -- February 15 2014
// -- in a std::map, when you call mFlag[x]
// -- if the iterator to the location of x doesn't exist
// -- it creates it with a default value, we later clean this
// -- up and remove that pointer to the empty data.
// -- savings are minimal, but worth it.
// -- David Simmerson (Omega)
snprintf ( buf, 10, "%d", mFlag[x] );
retStr.append ( buf );
// increment towards our final destination
x++;
}
// this cleans up our 'other' flags. ones that are 0 instead of 1
// with std::map's when you access them, it creates the default value
// so using mFlag[x], if it wasn't set before, it sets it. cleanFlags
// strips all those that are set to 0; minimal memory saved, but long-term
// it could be a healthy life saver.
cleanFlags();
return retStr;
}
void stringToFlag ( const std::string &str ) {
size_t x = 0;
while ( str[x] != '\0' ) {
if ( x > str.length() )
{ break; }
// only if we are set to 1 shall we add it :)
if ( str[x] == '1' ) {
mFlag[x] = true;
highestFlag = x;
}
// increment!
x++;
}
}
};
#endif