目前我已經實現了地圖的,像這樣的值的引用計數緩存:C++:在std :: map中引用計數值;是std :: multimap更好的選擇?
//filename or name of bitmap, reference count, memory location...
std::map<std::string, std::pair<long, BITMAP*> > _cache;
使用的std :: multimap中更好的選擇?
//filename or name of bitmap, memory location...
std::multimap<std::string, BITMAP*> _cache;
或者只是一個不同的方式呢?
- 編輯 -
下面是我的意圖它的目的是成爲一個私有類,它是嚴格的實用工具,用戶不會看到代碼的其餘部分的清晰度的特定類。對他們來說,他們只是創造一個雪碧。 注意:BITMAP
結構被認爲是私有的,創建/銷燬/修改一個結構的唯一方法是通過第三方C庫中的衆多功能之一,即使用原始指針的REQUIRE。
BitmapCache.h
#ifndef A2DE_CBITMAPCACHE_H
#define A2DE_CBITMAPCACHE_H
#include "../a2de_vals.h"
#include <allegro/file.h>
#include <allegro/gfx.h>
#include <allegro/draw.h>
#include <allegro/datafile.h>
#include <allegro/color.h>
#include <map>
#include <utility>
#include <string>
struct BITMAP;
_A2DE_BEGIN
class BitmapCache {
public:
static BITMAP* GetBitmap(std::string filename);
static BITMAP* StoreBitmap(std::string name, BITMAP* bmp);
static BITMAP* RetrieveBitmap(std::string name);
static std::string GetBitmapName(BITMAP* file);
static void RemoveBitmap(std::string name);
protected:
private:
static std::map<std::string, std::pair<long, BITMAP*> > _cache;
static void CleanCache();
};
_A2DE_END
#endif
BitmapCache.cpp
#include "CBitmapCache.h"
#include <algorithm>
#include <map>
_A2DE_BEGIN
//filename or name of bitmap, reference count, memory location...
typedef std::map<std::string, std::pair<long, BITMAP*> > MapStrBmp;
typedef MapStrBmp::iterator MapStrBmpIter;
MapStrBmp BitmapCache::_cache;
BITMAP* BitmapCache::GetBitmap(std::string filename) {
//Return NULL if a bad filename was passed.
if(filename.empty()) return NULL;
if(exists(filename.c_str()) == false) return NULL;
//Reduce incorrect results by forcing slash equality.
filename = fix_filename_slashes(&filename[0]);
//Clean the cache if it's dirty.
CleanCache();
//Search for requested BITMAP.
MapStrBmpIter _iter = _cache.find(filename);
//If found, return it.
if(_iter != _cache.end()) {
_iter->second.first++;
return _iter->second.second;
}
//Otherwise, create it, store it, then return it.
BITMAP* result = load_bmp(filename.c_str(), NULL);
if(result == NULL) return NULL;
_cache.insert(std::make_pair(filename, std::make_pair(static_cast<long>(1), result)));
return result;
}
BITMAP* BitmapCache::StoreBitmap(std::string name, BITMAP* bmp) {
if(name.empty() || bmp == NULL) return NULL;
CleanCache();
name = fix_filename_slashes(&name[0]);
MapStrBmpIter _iter = _cache.find(name);
if(_iter != _cache.end()) {
_iter->second.first++;
return _iter->second.second;
}
_cache.insert(std::make_pair(name, std::make_pair(static_cast<long>(1), bmp)));
return bmp;
}
BITMAP* BitmapCache::RetrieveBitmap(std::string name) {
if(name.empty()) return NULL;
name = fix_filename_slashes(&name[0]);
MapStrBmpIter _iter = _cache.find(name);
if(_iter != _cache.end()) {
_iter->second.first++;
return _iter->second.second;
}
return NULL;
}
void BitmapCache::RemoveBitmap(std::string name) {
if(name.empty()) return;
name = fix_filename_slashes(&name[0]);
MapStrBmpIter _iter = _cache.find(name);
if(_iter != _cache.end()) {
_iter->second.first--;
CleanCache();
}
}
std::string BitmapCache::GetBitmapName(BITMAP* file) {
if(file == NULL) return std::string("");
CleanCache();
MapStrBmpIter b = _cache.begin();
MapStrBmpIter e = _cache.end();
for(MapStrBmpIter _iter = b; _iter != e; ++_iter) {
if(_iter->second.second != file) continue;
return _iter->first;
}
return std::string("");
}
void BitmapCache::CleanCache() {
//Clean the cache of any bitmaps that are no longer referenced.
MapStrBmpIter b = _cache.begin();
MapStrBmpIter e = _cache.end();
for(MapStrBmpIter _iter = b; _iter != e; /* DO NOTHING */) {
if(_iter->second.first > 0) {
++_iter;
continue;
}
destroy_bitmap(_iter->second.second);
_iter->second.second = NULL;
_cache.erase(_iter++);
}
}
_A2DE_END
'std :: shared_ptr'。 – 2012-04-05 04:06:27