/* * 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