假设我有一个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

最佳答案

有两种设计模式可能会有所帮助:FactoryFlyWeight

通常,您的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上阅读,这里的情况是一个简并的情况,其中没有特有的部分,因此您不必拆分常见/地方包裹中的对象。

10-06 01:08
查看更多