假设我有一个Font
类,看起来像这样:
const unsigned int MAX_CHAR = 256; //better than dynamic I think?
struct BMchar
{
int x_ofs, y_ofs;
_uint32 x, y;
_uint32 width, height;
_uint32 x_advance;
};
struct BMkerninfo
{
_ushort first, second;
_ushort kerning;
};
class BM_FONT_CALL BMfont
{
public:
BMfont();
~BMfont(); //what will I free?
BMfont_Status Load(const char* fontName);
public:
float scale;
_uint32 tabSize;
_uint32 backTexture;
_uint32 frontTexture;
_uint32 textureSheet;
bool enableMasking;
bool hasBackground;
_uint32 base;
_uint32 lineHeight;
_uint32 pages;
_uint32 scaleW, scaleH;
_uint32 kerninfo_count;
BMkerninfo *kerninfo; //unused
BMchar chars[MAX_CHAR];
float texCoordBuff[MAX_CHAR * 8];
};
我有一个课程
Label
:class SWC_DLL SWC_Label
{
public:
SWC_Label ();
public:
void ShowText (const Point& basePoint, int baseW, int baseH);
public:
std::string text;
Point textCoord;
BMfont font;
T_Alignment textAlignment;
};
然后,对于所有这些,我担心,如您所见,
BMfont
类使用大量资源。我将继承类SWC_Label
到类SWC_Button
(是一个按钮,上面带有标签/文本)。现在,我希望此
SWC_Button
具有具有不同字体的功能。做这样的事情的更好和节省内存的方法是什么,我是否应该进行以下限制:仅定义定义数量的可用字体(在类标签中创建静态字体)?注意:我正在使用OpenGL制作UI
最佳答案
有两种设计模式可能会有所帮助:Factory
和FlyWeight
。
通常,您的SWC_Label
类不需要拥有一个BMFont
,只需要操纵一个即可。我的建议是使用字体的Factory
,它将在内部保留它所知道的字体的句柄。
简单的例子:
class FontFactory {
public:
typedef std::shared_ptr<BMFont> SharedFontPtr;
SharedFontPtr getFont(std::string const& name) const;
private:
std::map<std::string, SharedFontPtr> _fonts;
}; // class FontFactory
然后,
SWC_Label
类包含一个std::shared_ptr<BMFont>
(相对较轻的句柄),而不是一个完整的字体类。该主题有很多变体:
尚未加载的字体的延迟加载(来自
Factory
)在
std::weak_ptr
中保留一个Factory
引用,以尽可能减少内存占用根本不保留引用(虽然可能很浪费),因为您可能最终会在内存中保留多个副本
要优化具有大的公共共享部分但特有的流行部分的对象的内存消耗,您可能需要在
FlyWeight
上阅读,这里的情况是一个简并的情况,其中没有特有的部分,因此您不必拆分常见/地方包裹中的对象。