📄 catalogue.h
字号:
private:
// String comparator
GaStringComparator _comparator;
};
#if defined(GAL_STL_EXT_MSVC)
typedef hash_map<const char*, GaCatalogueEntry<T>*, GaCataolgueHashMapComparator> GaCataolgueHashMap;
#elif defined(GAL_STL_EXT_GNUC) || defined(GAL_STL_EXT_STLPORT)
typedef hash_map<const char*, GaCatalogueEntry<T>*, GaCataolgueHashMapComparator, GaCataolgueHashMapComparator> GaCataolgueHashMap;
#endif
/// <summary>Pointer to global instance of catalogue for type <c>T</c>.</summary>
GAL_API
static GaCatalogue<T>* _instance;
/// <summary>Hash table which stores keys and data of the catalogue.</summary>
GaCataolgueHashMap _entries;
public:
/// <summary>Returns reference to global instance of catalogue for type <c>T</c>.</summary>
/// <returns>Returns reference to global instance of catalogue for type <c>T</c>.</returns>
static GaCatalogue<T>& GACALL Instance() { return *_instance; }
/// <summary>Method makes global instance of catalogue if it wasn't instanced before.
/// This method must be called before using of global instance of catalogue. All built-in global instances of catalogues are instanced
/// in <see cref="GaInitialization" /> function.
///
/// This method is not thread safe.</summary>
static void GACALL MakeInstance()
{
if( !_instance )
_instance = new GaCatalogue();
}
/// <summary>Frees memory used by global instance of the catalogue. This method must be called before application quitting
/// application or unloading library. All built-in global instances of catalogues are freed in <see cref="GaFinalize" /> function.
///
/// This method is not thread safe.</summary>
static void GACALL FreeInstance()
{
if( _instance )
delete _instance;
}
/// <summary>Initializes empty catalogue</summary>
GaCatalogue() { }
/// <summary>Frees memory used by entries (keys and user data).</summary>
~GaCatalogue()
{
for( typename GaCataolgueHashMap::const_iterator it = _entries.begin(); it != (typename GaCataolgueHashMap::const_iterator)_entries.end(); it++ )
delete it->second;
_entries.clear();
}
/// <summary><c>Register</c> method adds data with specified key (name) to catalogue. If entry with specified key already exists
/// in catalogue and replace is set to <c>false</c>, insertion will fail because duplicate of keys are not allowed.
/// When replace is set to <c>true</c>, data in an entry with specified key are replaced or if such entry doesn't exist new entry
/// is added to catalogue. Key is copied and catalogue object takes over responsibility for memory used by data. Data must be located at heap.
///
/// This method is thread-safe.</summary>
/// <param name="name">key of new or existing entry.</param>
/// <param name="data">reference to data which will be stored in catalogue</param>
/// <param name="replace">tells method whether it should replace data in an entry if it exists with specified key.</param>
/// <returns>Method returns <c>true</c> if data is added or replaced successfully. If data cannot be added it returns <c>false</c>.</returns>
bool GACALL Register(const char* name,
T* data,
bool replace = false)
{
// no name - error?
if( !name )
return false;
//LOCK_THIS_OBJECT( lock );
// does it exist?
typename GaCataolgueHashMap::const_iterator it = _entries.find( name );
bool exists = it != (typename GaCataolgueHashMap::const_iterator)_entries.end();
if( exists && !replace )
// exists and no replacing - error
return false;
// erease if entry exists and replace is enabled
if( exists && replace )
{
delete it->second;
_entries.erase( name );
}
// make entry for data and insert to catalogue
GaCatalogueEntry<T>* new_entry = new GaCatalogueEntry<T>( name, data );
return _entries.insert( pair<const char*, GaCatalogueEntry<T>*>( name, new_entry ) ).second;
}
/// <summary><c>Unregister</c> method removes entry with specified key and frees memory used by it.
///
/// This method is thread-safe.</summary>
/// <param name="name">key of the desired entry.</param>
/// <returns>Method returns <c>true</c> if entry with specified key is removed successfully.
/// If entry cannot be found method returns <c>false</c>.</returns>
bool GACALL Unregister(const char* name)
{
LOCK_THIS_OBJECT( lock );
bool removed = false;
// exists?
typename GaCataolgueHashMap::const_iterator it = _entries.find( name );
if( it != _entries.end() )
{
// remove
delete it->second;
removed = _entries.erase( name ) > 0;
}
return removed;
}
/// <summary>This method is thread-safe.</summary>
/// <param name=name">key of the desired entry.</param>
/// <returns>Method returns pointer to catalogue entry with specified key. If such entry cannot be found, method returns <c>NULL</c> pointer.</returns>
inline GaCatalogueEntry<T>* GACALL GetEntry(const char* name) const
{
LOCK_THIS_OBJECT( lock );
// find entry and return pointer to entry
typename GaCataolgueHashMap::const_iterator it = _entries.find( name );
return it == _entries.end() ? NULL : it->second;
}
/// <summary>This method is thread-safe.</summary>
/// <param name="name">key of the desired entry.</param>
/// <returns>Method returns pointer to data of entry with specified key. If such entry cannot be found, method returns <c>NULL</c> pointer.</returns>
inline T* GACALL GetEntryData(const char* name) const
{
LOCK_THIS_OBJECT( lock );
// find entry and return pointer to data
typename GaCataolgueHashMap::const_iterator it = _entries.find( name );
return it == _entries.end() ? NULL : it->second->GetData();
}
/// <summary>This operator method is thread-safe.</summary>
/// <param name="name">key of the desired entry.</param>
/// <returns>Operator returns pointer to data of entry with specified key. If such entry cannot be found, operator returns <c>NULL</c> pointer.</returns>
inline T* GACALL operator [](const char* name) const { return GetEntryData( name ); }
// Returns all keys in catalogue
// This method allocates memory for array of pointers to keys and keys but caller is responsible for it.
// It returns pointer to array of keys and number of keys for which is memory allocated.
/// <summary><c>GetKeys</c> method returns all kesy in catalogue.
/// This method allocates memory for array of pointers to keys and keys but caller is responsible for it.
///
/// This method is thread-safe.</summary>
/// <param name="number">Reference to variable to which number of kesy will be stored.</param>
/// <returns>Method returns pointer to array of keys.</returns>
char** GACALL GetKeys(int& number) const
{
LOCK_THIS_OBJECT( lock );
// empty directory
if( _entries.size() == 0 )
{
number = 0;
return NULL;
}
number = _entries.size();
char** names = new char*[ number ];
// fill buffer with names
int i = 0;
for( typename GaCataolgueHashMap::const_iterator it = _entries.begin(); it != _entries.end(); ++it, i++ )
{
names[ i ] = new char[ it->second->GetNameLength() + 1 ];
strcpy( names[ i ], it->second->GetName() );
}
return names;
}
/// <summary>This method is thread-safe.</summary>
/// <returns>Method returns number of entries in catalogue.</returns>
inline int GACALL GetCount() const
{
LOCK_THIS_OBJECT( lock );
return _entries.size();
}
/// <summary><c>IsExist</c> method checks existence of entry with specified key.
///
/// This method is thread-safe.</summary>
/// <param name="name">key of the desired entry.</param>
/// <returns>Method returns <c>true</c> if entry with specified key exists in catalogue, otherwise return <c>false</c>.</returns>
inline bool GACALL IsExist(const char* name) const
{
LOCK_THIS_OBJECT( lock );
return _entries.count( name ) > 0;
}
};
#if defined(GAL_API_EXPORTING)
template <typename T>
GaCatalogue<T>* GaCatalogue<T>::_instance = NULL;
#else
#if defined(GAL_PLATFORM_NIX)
#if !defined(GAL_SYNTAX_INTL) && !defined(GAL_SYNTAX_SUNC)
template <typename T>
extern GaCatalogue<T>* GaCatalogue<T>::_instance;
#endif
#endif
#endif
} // Common
#endif //__GA_CATALOGUE_H__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -