DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

Dict.h (12062B)


      1 /*
      2 ===========================================================================
      3 
      4 Doom 3 BFG Edition GPL Source Code
      5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 
      6 
      7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").  
      8 
      9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
     10 it under the terms of the GNU General Public License as published by
     11 the Free Software Foundation, either version 3 of the License, or
     12 (at your option) any later version.
     13 
     14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
     15 but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 GNU General Public License for more details.
     18 
     19 You should have received a copy of the GNU General Public License
     20 along with Doom 3 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code.  If not, please request a copy in writing from id Software at the address below.
     23 
     24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
     25 
     26 ===========================================================================
     27 */
     28 
     29 #ifndef __DICT_H__
     30 #define __DICT_H__
     31 
     32 class idSerializer;
     33 
     34 /*
     35 ===============================================================================
     36 
     37 Key/value dictionary
     38 
     39 This is a dictionary class that tracks an arbitrary number of key / value
     40 pair combinations. It is used for map entity spawning, GUI state management,
     41 and other things.
     42 
     43 Keys are compared case-insensitive.
     44 
     45 Does not allocate memory until the first key/value pair is added.
     46 
     47 ===============================================================================
     48 */
     49 
     50 class idKeyValue {
     51 	friend class idDict;
     52 
     53 public:
     54 	const idStr &		GetKey() const { return *key; }
     55 	const idStr &		GetValue() const { return *value; }
     56 
     57 	size_t				Allocated() const { return key->Allocated() + value->Allocated(); }
     58 	size_t				Size() const { return sizeof( *this ) + key->Size() + value->Size(); }
     59 
     60 	bool				operator==( const idKeyValue &kv ) const { return ( key == kv.key && value == kv.value ); }
     61 
     62 private:
     63 	const idPoolStr *	key;
     64 	const idPoolStr *	value;
     65 };
     66 
     67 /*
     68 ================================================
     69 idSort_KeyValue 
     70 ================================================
     71 */
     72 class idSort_KeyValue : public idSort_Quick< idKeyValue, idSort_KeyValue > {
     73 public:
     74 	int Compare( const idKeyValue & a, const idKeyValue & b ) const { return a.GetKey().Icmp( b.GetKey() ); }
     75 };
     76 
     77 class idDict {
     78 public:
     79 						idDict();
     80 						idDict( const idDict &other );	// allow declaration with assignment
     81 						~idDict();
     82 
     83 						// set the granularity for the index
     84 	void				SetGranularity( int granularity );
     85 						// set hash size
     86 	void				SetHashSize( int hashSize );
     87 						// clear existing key/value pairs and copy all key/value pairs from other
     88 	idDict &			operator=( const idDict &other );
     89 						// copy from other while leaving existing key/value pairs in place
     90 	void				Copy( const idDict &other );
     91 						// clear existing key/value pairs and transfer key/value pairs from other
     92 	void				TransferKeyValues( idDict &other );
     93 						// parse dict from parser
     94 	bool				Parse( idParser &parser );
     95 						// copy key/value pairs from other dict not present in this dict
     96 	void				SetDefaults( const idDict *dict );
     97 						// clear dict freeing up memory
     98 	void				Clear();
     99 						// print the dict
    100 	void				Print() const;
    101 
    102 	size_t				Allocated() const;
    103 	size_t				Size() const { return sizeof( *this ) + Allocated(); }
    104 
    105 	void				Set( const char *key, const char *value );
    106 	void				SetFloat( const char *key, float val );
    107 	void				SetInt( const char *key, int val );
    108 	void				SetBool( const char *key, bool val );
    109 	void				SetVector( const char *key, const idVec3 &val );
    110 	void				SetVec2( const char *key, const idVec2 &val );
    111 	void				SetVec4( const char *key, const idVec4 &val );
    112 	void				SetAngles( const char *key, const idAngles &val );
    113 	void				SetMatrix( const char *key, const idMat3 &val );
    114 
    115 						// these return default values of 0.0, 0 and false
    116 	const char *		GetString( const char *key, const char *defaultString = "" ) const;
    117 	float				GetFloat( const char *key, const char *defaultString ) const;
    118 	int					GetInt( const char *key, const char *defaultString ) const;
    119 	bool				GetBool( const char *key, const char *defaultString ) const;
    120 	float				GetFloat( const char *key, const float defaultFloat = 0.0f ) const;
    121 	int					GetInt( const char *key, const int defaultInt = 0 ) const;
    122 	bool				GetBool( const char *key, const bool defaultBool = false ) const;
    123 	idVec3				GetVector( const char *key, const char *defaultString = NULL ) const;
    124 	idVec2				GetVec2( const char *key, const char *defaultString = NULL ) const;
    125 	idVec4				GetVec4( const char *key, const char *defaultString = NULL ) const;
    126 	idAngles			GetAngles( const char *key, const char *defaultString = NULL ) const;
    127 	idMat3				GetMatrix( const char *key, const char *defaultString = NULL ) const;
    128 
    129 	bool				GetString( const char *key, const char *defaultString, const char **out ) const;
    130 	bool				GetString( const char *key, const char *defaultString, idStr &out ) const;
    131 	bool				GetFloat( const char *key, const char *defaultString, float &out ) const;
    132 	bool				GetInt( const char *key, const char *defaultString, int &out ) const;
    133 	bool				GetBool( const char *key, const char *defaultString, bool &out ) const;
    134 	bool				GetFloat( const char *key, const float defaultFloat, float &out ) const;
    135 	bool				GetInt( const char *key, const int defaultInt, int &out ) const;
    136 	bool				GetBool( const char *key, const bool defaultBool, bool &out ) const;
    137 	bool				GetVector( const char *key, const char *defaultString, idVec3 &out ) const;
    138 	bool				GetVec2( const char *key, const char *defaultString, idVec2 &out ) const;
    139 	bool				GetVec4( const char *key, const char *defaultString, idVec4 &out ) const;
    140 	bool				GetAngles( const char *key, const char *defaultString, idAngles &out ) const;
    141 	bool				GetMatrix( const char *key, const char *defaultString, idMat3 &out ) const;
    142 
    143 	int					GetNumKeyVals() const;
    144 	const idKeyValue *	GetKeyVal( int index ) const;
    145 						// returns the key/value pair with the given key
    146 						// returns NULL if the key/value pair does not exist
    147 	const idKeyValue *	FindKey( const char *key ) const;
    148 						// returns the index to the key/value pair with the given key
    149 						// returns -1 if the key/value pair does not exist
    150 	int					FindKeyIndex( const char *key ) const;
    151 						// delete the key/value pair with the given key
    152 	void				Delete( const char *key );
    153 						// finds the next key/value pair with the given key prefix.
    154 						// lastMatch can be used to do additional searches past the first match.
    155 	const idKeyValue *	MatchPrefix( const char *prefix, const idKeyValue *lastMatch = NULL ) const;
    156 						// randomly chooses one of the key/value pairs with the given key prefix and returns it's value
    157 	const char *		RandomPrefix( const char *prefix, idRandom &random ) const;
    158 
    159 	void				WriteToFileHandle( idFile *f ) const;
    160 	void				ReadFromFileHandle( idFile *f );
    161 
    162 	void				WriteToIniFile( idFile * f ) const;
    163 	bool				ReadFromIniFile( idFile * f );
    164 
    165 	void				Serialize( idSerializer & ser );
    166 
    167 						// returns a unique checksum for this dictionary's content
    168 	int					Checksum() const;
    169 
    170 	static void			Init();
    171 	static void			Shutdown();
    172 
    173 	static void			ShowMemoryUsage_f( const idCmdArgs &args );
    174 	static void			ListKeys_f( const idCmdArgs &args );
    175 	static void			ListValues_f( const idCmdArgs &args );
    176 
    177 private:
    178 	idList<idKeyValue>	args;
    179 	idHashIndex			argHash;
    180 
    181 	static idStrPool	globalKeys;
    182 	static idStrPool	globalValues;
    183 };
    184 
    185 
    186 ID_INLINE idDict::idDict() {
    187 	args.SetGranularity( 16 );
    188 	argHash.SetGranularity( 16 );
    189 	argHash.Clear( 128, 16 );
    190 }
    191 
    192 ID_INLINE idDict::idDict( const idDict &other ) {
    193 	*this = other;
    194 }
    195 
    196 ID_INLINE idDict::~idDict() {
    197 	Clear();
    198 }
    199 
    200 ID_INLINE void idDict::SetGranularity( int granularity ) {
    201 	args.SetGranularity( granularity );
    202 	argHash.SetGranularity( granularity );
    203 }
    204 
    205 ID_INLINE void idDict::SetHashSize( int hashSize ) {
    206 	if ( args.Num() == 0 ) {
    207 		argHash.Clear( hashSize, 16 );
    208 	}
    209 }
    210 
    211 ID_INLINE void idDict::SetFloat( const char *key, float val ) {
    212 	Set( key, va( "%f", val ) );
    213 }
    214 
    215 ID_INLINE void idDict::SetInt( const char *key, int val ) {
    216 	Set( key, va( "%i", val ) );
    217 }
    218 
    219 ID_INLINE void idDict::SetBool( const char *key, bool val ) {
    220 	Set( key, va( "%i", val ) );
    221 }
    222 
    223 ID_INLINE void idDict::SetVector( const char *key, const idVec3 &val ) {
    224 	Set( key, val.ToString() );
    225 }
    226 
    227 ID_INLINE void idDict::SetVec4( const char *key, const idVec4 &val ) {
    228 	Set( key, val.ToString() );
    229 }
    230 
    231 ID_INLINE void idDict::SetVec2( const char *key, const idVec2 &val ) {
    232 	Set( key, val.ToString() );
    233 }
    234 
    235 ID_INLINE void idDict::SetAngles( const char *key, const idAngles &val ) {
    236 	Set( key, val.ToString() );
    237 }
    238 
    239 ID_INLINE void idDict::SetMatrix( const char *key, const idMat3 &val ) {
    240 	Set( key, val.ToString() );
    241 }
    242 
    243 ID_INLINE bool idDict::GetString( const char *key, const char *defaultString, const char **out ) const {
    244 	const idKeyValue *kv = FindKey( key );
    245 	if ( kv ) {
    246 		*out = kv->GetValue();
    247 		return true;
    248 	}
    249 	*out = defaultString;
    250 	return false;
    251 }
    252 
    253 ID_INLINE bool idDict::GetString( const char *key, const char *defaultString, idStr &out ) const {
    254 	const idKeyValue *kv = FindKey( key );
    255 	if ( kv ) {
    256 		out = kv->GetValue();
    257 		return true;
    258 	}
    259 	out = defaultString;
    260 	return false;
    261 }
    262 
    263 ID_INLINE const char *idDict::GetString( const char *key, const char *defaultString ) const {
    264 	const idKeyValue *kv = FindKey( key );
    265 	if ( kv ) {
    266 		return kv->GetValue();
    267 	}
    268 	return defaultString;
    269 }
    270 
    271 ID_INLINE float idDict::GetFloat( const char *key, const char *defaultString ) const {
    272 	return atof( GetString( key, defaultString ) );
    273 }
    274 
    275 ID_INLINE int idDict::GetInt( const char *key, const char *defaultString ) const {
    276 	return atoi( GetString( key, defaultString ) );
    277 }
    278 
    279 ID_INLINE bool idDict::GetBool( const char *key, const char *defaultString ) const {
    280 	return ( atoi( GetString( key, defaultString ) ) != 0 );
    281 }
    282 
    283 ID_INLINE float idDict::GetFloat( const char *key, const float defaultFloat ) const {
    284 	const idKeyValue *kv = FindKey( key );
    285 	if ( kv ) {
    286 		return atof( kv->GetValue() );
    287 	}
    288 	return defaultFloat;
    289 }
    290 
    291 ID_INLINE int idDict::GetInt( const char *key, int defaultInt ) const {
    292 	const idKeyValue *kv = FindKey( key );
    293 	if ( kv ) {
    294 		return atoi( kv->GetValue() );
    295 	}
    296 	return defaultInt;
    297 }
    298 
    299 ID_INLINE bool idDict::GetBool( const char *key, const bool defaultBool ) const {
    300 	const idKeyValue *kv = FindKey( key );
    301 	if ( kv ) {
    302 		return atoi( kv->GetValue() ) != 0;
    303 	}
    304 	return defaultBool;
    305 }
    306 
    307 ID_INLINE idVec3 idDict::GetVector( const char *key, const char *defaultString ) const {
    308 	idVec3 out;
    309 	GetVector( key, defaultString, out );
    310 	return out;
    311 }
    312 
    313 ID_INLINE idVec2 idDict::GetVec2( const char *key, const char *defaultString ) const {
    314 	idVec2 out;
    315 	GetVec2( key, defaultString, out );
    316 	return out;
    317 }
    318 
    319 ID_INLINE idVec4 idDict::GetVec4( const char *key, const char *defaultString ) const {
    320 	idVec4 out;
    321 	GetVec4( key, defaultString, out );
    322 	return out;
    323 }
    324 
    325 ID_INLINE idAngles idDict::GetAngles( const char *key, const char *defaultString ) const {
    326 	idAngles out;
    327 	GetAngles( key, defaultString, out );
    328 	return out;
    329 }
    330 
    331 ID_INLINE idMat3 idDict::GetMatrix( const char *key, const char *defaultString ) const {
    332 	idMat3 out;
    333 	GetMatrix( key, defaultString, out );
    334 	return out;
    335 }
    336 
    337 ID_INLINE int idDict::GetNumKeyVals() const {
    338 	return args.Num();
    339 }
    340 
    341 ID_INLINE const idKeyValue *idDict::GetKeyVal( int index ) const {
    342 	if ( index >= 0 && index < args.Num() ) {
    343 		return &args[ index ];
    344 	}
    345 	return NULL;
    346 }
    347 
    348 #endif /* !__DICT_H__ */