/* Copyright (C) 2001-2006, William Joseph. All Rights Reserved. This file is part of GtkRadiant. GtkRadiant is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. GtkRadiant is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GtkRadiant; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #if !defined( INCLUDED_NAMEKEYS_H ) #define INCLUDED_NAMEKEYS_H #include #include #include "generic/static.h" #include "entitylib.h" #include "namespace.h" inline bool string_is_integer( const char* string ){ strtol( string, const_cast( &string ), 10 ); return *string == '\0'; } typedef bool ( *KeyIsNameFunc )( const char* key ); class KeyIsName { public: KeyIsNameFunc m_keyIsName; const char* m_nameKey; KeyIsName(){ } }; typedef MemberCaller1 KeyValueAssignCaller; typedef MemberCaller1 KeyValueAttachCaller; typedef MemberCaller1 KeyValueDetachCaller; class NameKeys : public Entity::Observer, public Namespaced { Namespace* m_namespace; EntityKeyValues& m_entity; KeyIsNameFunc m_keyIsName; NameKeys( const NameKeys& other ); NameKeys& operator=( const NameKeys& other ); typedef std::map KeyValues; KeyValues m_keyValues; void insertName( const char* key, EntityKeyValue& value ){ if ( m_namespace != 0 && m_keyIsName( key ) ) { //globalOutputStream() << "insert " << key << "\n"; m_namespace->attach( KeyValueAssignCaller( value ), KeyValueAttachCaller( value ) ); } } void eraseName( const char* key, EntityKeyValue& value ){ if ( m_namespace != 0 && m_keyIsName( key ) ) { //globalOutputStream() << "erase " << key << "\n"; m_namespace->detach( KeyValueAssignCaller( value ), KeyValueDetachCaller( value ) ); } } void insertAll(){ for ( KeyValues::iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i ) { insertName( ( *i ).first.c_str(), *( *i ).second ); } } void eraseAll(){ for ( KeyValues::iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i ) { eraseName( ( *i ).first.c_str(), *( *i ).second ); } } public: NameKeys( EntityKeyValues& entity ) : m_namespace( 0 ), m_entity( entity ), m_keyIsName( Static::instance().m_keyIsName ){ m_entity.attach( *this ); } ~NameKeys(){ m_entity.detach( *this ); } void setNamespace( Namespace& space ){ eraseAll(); m_namespace = &space; insertAll(); } void setKeyIsName( KeyIsNameFunc keyIsName ){ eraseAll(); m_keyIsName = keyIsName; insertAll(); } void insert( const char* key, EntityKeyValue& value ){ m_keyValues.insert( KeyValues::value_type( key, &value ) ); insertName( key, value ); } void erase( const char* key, EntityKeyValue& value ){ eraseName( key, value ); m_keyValues.erase( key ); } }; inline bool keyIsNameDoom3( const char* key ){ return string_equal( key, "target" ) || ( string_equal_n( key, "target", 6 ) && string_is_integer( key + 6 ) ) || string_equal( key, "name" ); } inline bool keyIsNameDoom3Doom3Group( const char* key ){ return keyIsNameDoom3( key ) || string_equal( key, "model" ); } inline bool keyIsNameQuake3( const char* key ){ return string_equal( key, "target" ) || string_equal( key, "targetname" ) || string_equal( key, "killtarget" ) || ( string_equal_n( key, "target", 6 ) && string_is_integer( key + 6 ) ); // Nexuiz } #endif