diff --git a/source/gui/CGUI.cpp b/source/gui/CGUI.cpp index d9d1f086db..bfb549561d 100644 --- a/source/gui/CGUI.cpp +++ b/source/gui/CGUI.cpp @@ -485,8 +485,7 @@ void CGUI::Destroy() { // We can use the map to delete all // now we don't want to cancel all if one Destroy fails - map_pObjects::iterator it; - for (it = m_pAllObjects.begin(); it != m_pAllObjects.end(); ++it) + for (map_pObjects::iterator it = m_pAllObjects.begin(); it != m_pAllObjects.end(); ++it) { try { @@ -502,12 +501,10 @@ void CGUI::Destroy() delete it->second; } - for (std::map::iterator it2 = m_Sprites.begin(); it2 != m_Sprites.end(); ++it2) - for (std::vector::iterator it3 = it2->second.m_Images.begin(); it3 != it2->second.m_Images.end(); ++it3) - delete it3->m_Effects; - // Clear all m_pAllObjects.clear(); + for(std::map::iterator it = m_Sprites.begin(); it != m_Sprites.end(); ++it) + delete it->second; m_Sprites.clear(); m_Icons.clear(); } @@ -1454,7 +1451,7 @@ void CGUI::Xeromyces_ReadScript(XMBElement Element, CXeromyces* pFile, boost::un void CGUI::Xeromyces_ReadSprite(XMBElement Element, CXeromyces* pFile) { // Sprite object we're adding - CGUISprite sprite; + CGUISprite* Sprite = new CGUISprite; // and what will be its reference name CStr name; @@ -1487,7 +1484,7 @@ void CGUI::Xeromyces_ReadSprite(XMBElement Element, CXeromyces* pFile) if (ElementName == "image") { - Xeromyces_ReadImage(child, pFile, sprite); + Xeromyces_ReadImage(child, pFile, *Sprite); } else if (ElementName == "effect") { @@ -1510,9 +1507,9 @@ void CGUI::Xeromyces_ReadSprite(XMBElement Element, CXeromyces* pFile) // Apply the effects to every image (unless the image overrides it with // different effects) if (effects) - for (std::vector::iterator it = sprite.m_Images.begin(); it != sprite.m_Images.end(); ++it) - if (! it->m_Effects) - it->m_Effects = new SGUIImageEffects(*effects); // do a copy just so it can be deleted correctly later + for (std::vector::iterator it = Sprite->m_Images.begin(); it != Sprite->m_Images.end(); ++it) + if (! (*it)->m_Effects) + (*it)->m_Effects = new SGUIImageEffects(*effects); // do a copy just so it can be deleted correctly later delete effects; @@ -1520,18 +1517,18 @@ void CGUI::Xeromyces_ReadSprite(XMBElement Element, CXeromyces* pFile) // Add Sprite // - m_Sprites[name] = sprite; + m_Sprites[name] = Sprite; } void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite &parent) { // Image object we're adding - SGUIImage image; + SGUIImage* Image = new SGUIImage; // Set defaults to "0 0 100% 100%" - image.m_TextureSize = CClientArea(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100)); - image.m_Size = CClientArea(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100)); + Image->m_TextureSize = CClientArea(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100)); + Image->m_Size = CClientArea(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100)); // TODO Gee: Setup defaults here (or maybe they are in the SGUIImage ctor) @@ -1549,7 +1546,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite if (attr_name == "texture") { - image.m_TextureName = VfsPath("art/textures/ui") / attr_value; + Image->m_TextureName = VfsPath("art/textures/ui") / attr_value; } else if (attr_name == "size") @@ -1557,7 +1554,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite CClientArea ca; if (!GUI::ParseString(attr_value, ca)) LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); - else image.m_Size = ca; + else Image->m_Size = ca; } else if (attr_name == "texture_size") @@ -1565,7 +1562,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite CClientArea ca; if (!GUI::ParseString(attr_value, ca)) LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); - else image.m_TextureSize = ca; + else Image->m_TextureSize = ca; } else if (attr_name == "real_texture_placement") @@ -1573,7 +1570,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite CRect rect; if (!GUI::ParseString(attr_value, rect)) LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); - else image.m_TexturePlacementInFile = rect; + else Image->m_TexturePlacementInFile = rect; } else if (attr_name == "cell_size") @@ -1581,7 +1578,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite CSize size; if (!GUI::ParseString(attr_value, size)) LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); - else image.m_CellSize = size; + else Image->m_CellSize = size; } else if (attr_name == "fixed_h_aspect_ratio") @@ -1589,7 +1586,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite float val; if (!GUI::ParseString(attr_value, val)) LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); - else image.m_FixedHAspectRatio = val; + else Image->m_FixedHAspectRatio = val; } else if (attr_name == "round_coordinates") @@ -1597,17 +1594,17 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite bool b; if (!GUI::ParseString(attr_value, b)) LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); - else image.m_RoundCoordinates = b; + else Image->m_RoundCoordinates = b; } else if (attr_name == "wrap_mode") { if (attr_value == L"repeat") - image.m_WrapMode = GL_REPEAT; + Image->m_WrapMode = GL_REPEAT; else if (attr_value == L"mirrored_repeat") - image.m_WrapMode = GL_MIRRORED_REPEAT; + Image->m_WrapMode = GL_MIRRORED_REPEAT; else if (attr_value == L"clamp_to_edge") - image.m_WrapMode = GL_CLAMP_TO_EDGE; + Image->m_WrapMode = GL_CLAMP_TO_EDGE; else LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); } @@ -1617,7 +1614,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite float z_level; if (!GUI::ParseString(attr_value, z_level)) LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); - else image.m_DeltaZ = z_level/100.f; + else Image->m_DeltaZ = z_level/100.f; } else if (attr_name == "backcolor") @@ -1625,7 +1622,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite CColor color; if (!GUI::ParseString(attr_value, color)) LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); - else image.m_BackColor = color; + else Image->m_BackColor = color; } else if (attr_name == "bordercolor") @@ -1633,7 +1630,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite CColor color; if (!GUI::ParseString(attr_value, color)) LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); - else image.m_BorderColor = color; + else Image->m_BorderColor = color; } else if (attr_name == "border") @@ -1641,7 +1638,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite bool b; if (!GUI::ParseString(attr_value, b)) LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); - else image.m_Border = b; + else Image->m_Border = b; } else { @@ -1657,14 +1654,14 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite CStr ElementName (pFile->GetElementString(child.GetNodeName())); if (ElementName == "effect") { - if (image.m_Effects) + if (Image->m_Effects) { LOGERROR(L"GUI must not have more than one "); } else { - image.m_Effects = new SGUIImageEffects; - Xeromyces_ReadEffects(child, pFile, *image.m_Effects); + Image->m_Effects = new SGUIImageEffects; + Xeromyces_ReadEffects(child, pFile, *Image->m_Effects); } } else @@ -1677,7 +1674,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite // Input // - parent.AddImage(image); + parent.AddImage(Image); } void CGUI::Xeromyces_ReadEffects(XMBElement Element, CXeromyces* pFile, SGUIImageEffects &effects) diff --git a/source/gui/CGUI.h b/source/gui/CGUI.h index a6abab3d7f..634353b213 100644 --- a/source/gui/CGUI.h +++ b/source/gui/CGUI.h @@ -670,7 +670,7 @@ private: //-------------------------------------------------------- // Sprites - std::map m_Sprites; + std::map m_Sprites; // Styles std::map m_Styles; diff --git a/source/gui/CGUISprite.cpp b/source/gui/CGUISprite.cpp index a71902ade2..783ec28627 100644 --- a/source/gui/CGUISprite.cpp +++ b/source/gui/CGUISprite.cpp @@ -18,7 +18,20 @@ #include "precompiled.h" #include "CGUISprite.h" -void CGUISpriteInstance::Draw(CRect Size, int CellID, std::map &Sprites, float Z) const +CGUISprite::~CGUISprite() +{ + for (std::vector::iterator it = m_Images.begin(); it != m_Images.end(); it++) + { + delete *it; + } +} + +void CGUISprite::AddImage(SGUIImage* image) +{ + m_Images.push_back(image); +} + +void CGUISpriteInstance::Draw(CRect Size, int CellID, std::map &Sprites, float Z) const { if (m_CachedSize != Size || m_CachedCellID != CellID) { diff --git a/source/gui/CGUISprite.h b/source/gui/CGUISprite.h index 52f881e93c..6eb442b8d6 100644 --- a/source/gui/CGUISprite.h +++ b/source/gui/CGUISprite.h @@ -69,7 +69,6 @@ struct SGUIImageEffects bool m_Greyscale; }; - /** * A CGUISprite is actually a collage of several real * sprites, this struct represents is such real sprite. @@ -81,6 +80,11 @@ struct SGUIImage m_Effects(NULL), m_Border(false), m_DeltaZ(0.f) { } + + ~SGUIImage() + { + delete m_Effects; + } // Filename of the texture VfsPath m_TextureName; @@ -135,8 +139,9 @@ struct SGUIImage * way of declaring delta-z. */ float m_DeltaZ; -}; + NONCOPYABLE(SGUIImage); +}; /** * The GUI sprite, is actually several real sprites (images) @@ -151,17 +156,19 @@ class CGUISprite { public: CGUISprite() {} - virtual ~CGUISprite() {} + virtual ~CGUISprite(); /** * Adds an image to the sprite collage. * * @param image Adds this image to the sprite collage. */ - void AddImage(const SGUIImage &image) { m_Images.push_back(image); } + void AddImage(SGUIImage*); /// List of images - std::vector m_Images; + std::vector m_Images; + + NONCOPYABLE(CGUISprite); }; #include "GUIRenderer.h" @@ -176,7 +183,7 @@ public: CGUISpriteInstance(const CStr& SpriteName); CGUISpriteInstance(const CGUISpriteInstance &Sprite); CGUISpriteInstance &operator=(const CStr& SpriteName); - void Draw(CRect Size, int CellID, std::map &Sprites, float Z) const; + void Draw(CRect Size, int CellID, std::map& Sprites, float Z) const; void Invalidate(); bool IsEmpty() const; const CStr& GetName() { return m_SpriteName; } diff --git a/source/gui/GUIRenderer.cpp b/source/gui/GUIRenderer.cpp index 95311584e8..26ccdc8227 100644 --- a/source/gui/GUIRenderer.cpp +++ b/source/gui/GUIRenderer.cpp @@ -56,7 +56,7 @@ DrawCalls& DrawCalls::operator=(const DrawCalls&) } -void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, const CRect &Size, int CellID, std::map &Sprites) +void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, const CRect &Size, int CellID, std::map &Sprites) { // This is called only when something has changed (like the size of the // sprite), so it doesn't need to be particularly efficient. @@ -71,7 +71,7 @@ void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, return; - std::map::iterator it (Sprites.find(SpriteName)); + std::map::iterator it (Sprites.find(SpriteName)); if (it == Sprites.end()) { // Sprite not found. Check whether this a special sprite: @@ -84,26 +84,26 @@ void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, if (SpriteName.substr(0, 10) == "stretched:") { // TODO: Should check (nicely) that this is a valid file? - SGUIImage Image; + SGUIImage* Image = new SGUIImage; // Allow grayscale images for disabled portraits if (SpriteName.substr(10, 10) == "grayscale:") { - Image.m_TextureName = VfsPath("art/textures/ui") / wstring_from_utf8(SpriteName.substr(20)); - Image.m_Effects = new SGUIImageEffects; - Image.m_Effects->m_Greyscale = true; + Image->m_TextureName = VfsPath("art/textures/ui") / wstring_from_utf8(SpriteName.substr(20)); + Image->m_Effects = new SGUIImageEffects; + Image->m_Effects->m_Greyscale = true; } else { - Image.m_TextureName = VfsPath("art/textures/ui") / wstring_from_utf8(SpriteName.substr(10)); + Image->m_TextureName = VfsPath("art/textures/ui") / wstring_from_utf8(SpriteName.substr(10)); } CClientArea ca(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100)); - Image.m_Size = ca; - Image.m_TextureSize = ca; + Image->m_Size = ca; + Image->m_TextureSize = ca; - CGUISprite Sprite; - Sprite.AddImage(Image); + CGUISprite* Sprite = new CGUISprite; + Sprite->AddImage(Image); Sprites[SpriteName] = Sprite; @@ -113,22 +113,22 @@ void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, else if (SpriteName.substr(0, 8) == "cropped:") { // TODO: Should check (nicely) that this is a valid file? - SGUIImage Image; + SGUIImage* Image = new SGUIImage; double xRatio = SpriteName.BeforeFirst(",").AfterLast("(").ToDouble(); double yRatio = SpriteName.BeforeFirst(")").AfterLast(",").ToDouble(); int PathStart = SpriteName.Find(")") + 1; - Image.m_TextureName = VfsPath("art/textures/ui") / wstring_from_utf8(SpriteName.substr(PathStart)); + Image->m_TextureName = VfsPath("art/textures/ui") / wstring_from_utf8(SpriteName.substr(PathStart)); CClientArea ca(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100)); CClientArea cb(CRect(0, 0, 0, 0), CRect(0, 0, 100/xRatio, 100/yRatio)); - Image.m_Size = ca; - Image.m_TextureSize = cb; + Image->m_Size = ca; + Image->m_TextureSize = cb; - CGUISprite Sprite; - Sprite.AddImage(Image); + CGUISprite* Sprite = new CGUISprite; + Sprite->AddImage(Image); Sprites[SpriteName] = Sprite; @@ -147,16 +147,16 @@ void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, return; } - SGUIImage image; + SGUIImage* Image = new SGUIImage; - image.m_BackColor = color; + Image->m_BackColor = color; CClientArea ca(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100)); - image.m_Size = ca; - image.m_TextureSize = ca; + Image->m_Size = ca; + Image->m_TextureSize = ca; - CGUISprite Sprite; - Sprite.AddImage(image); + CGUISprite* Sprite = new CGUISprite; + Sprite->AddImage(Image); Sprites[SpriteName] = Sprite; @@ -171,16 +171,16 @@ void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, } } - Calls.reserve(it->second.m_Images.size()); + Calls.reserve(it->second->m_Images.size()); // Iterate through all the sprite's images, loading the texture and // calculating the texture coordinates - std::vector::const_iterator cit; - for (cit = it->second.m_Images.begin(); cit != it->second.m_Images.end(); ++cit) + std::vector::const_iterator cit; + for (cit = it->second->m_Images.begin(); cit != it->second->m_Images.end(); ++cit) { - SDrawCall Call(&*cit); // pointers are safe since we never modify sprites/images after startup + SDrawCall Call(*cit); // pointers are safe since we never modify sprites/images after startup - CRect ObjectSize = cit->m_Size.GetClientArea(Size); + CRect ObjectSize = (*cit)->m_Size.GetClientArea(Size); if (ObjectSize.GetWidth() == 0.0 || ObjectSize.GetHeight() == 0.0) { @@ -189,7 +189,7 @@ void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, } Call.m_Vertices = ObjectSize; - if (cit->m_RoundCoordinates) + if ((*cit)->m_RoundCoordinates) { // Round the vertex coordinates to integers, to avoid ugly filtering artifacts Call.m_Vertices.left = (int)(Call.m_Vertices.left + 0.5f); @@ -198,10 +198,10 @@ void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, Call.m_Vertices.bottom = (int)(Call.m_Vertices.bottom + 0.5f); } - if (! cit->m_TextureName.empty()) + if (!(*cit)->m_TextureName.empty()) { - CTextureProperties textureProps(cit->m_TextureName); - textureProps.SetWrap(cit->m_WrapMode); + CTextureProperties textureProps((*cit)->m_TextureName); + textureProps.SetWrap((*cit)->m_WrapMode); CTexturePtr texture = g_Renderer.GetTextureManager().CreateTexture(textureProps); texture->Prefetch(); Call.m_HasTexture = true; @@ -216,29 +216,29 @@ void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, { Call.m_HasTexture = false; // Enable blending if it's transparent (allowing a little error in the calculations) - Call.m_EnableBlending = !(fabs(cit->m_BackColor.a - 1.0f) < 0.0000001f); + Call.m_EnableBlending = !(fabs((*cit)->m_BackColor.a - 1.0f) < 0.0000001f); } - Call.m_BackColor = cit->m_BackColor; - Call.m_BorderColor = cit->m_Border ? cit->m_BorderColor : CColor(); - Call.m_DeltaZ = cit->m_DeltaZ; + Call.m_BackColor = (*cit)->m_BackColor; + Call.m_BorderColor = (*cit)->m_Border ? (*cit)->m_BorderColor : CColor(); + Call.m_DeltaZ = (*cit)->m_DeltaZ; if (!Call.m_HasTexture) { Call.m_Shader = g_Renderer.GetShaderManager().LoadEffect(str_gui_solid); } - else if (cit->m_Effects) + else if ((*cit)->m_Effects) { - if (cit->m_Effects->m_AddColor != CColor()) + if ((*cit)->m_Effects->m_AddColor != CColor()) { Call.m_Shader = g_Renderer.GetShaderManager().LoadEffect(str_gui_add); - Call.m_ShaderColorParameter = cit->m_Effects->m_AddColor; + Call.m_ShaderColorParameter = (*cit)->m_Effects->m_AddColor; // Always enable blending if something's being subtracted from // the alpha channel - if (cit->m_Effects->m_AddColor.a < 0.f) + if ((*cit)->m_Effects->m_AddColor.a < 0.f) Call.m_EnableBlending = true; } - else if (cit->m_Effects->m_Greyscale) + else if ((*cit)->m_Effects->m_Greyscale) { Call.m_Shader = g_Renderer.GetShaderManager().LoadEffect(str_gui_grayscale); } diff --git a/source/gui/GUIRenderer.h b/source/gui/GUIRenderer.h index a99cc2e25f..1ddf1601fd 100644 --- a/source/gui/GUIRenderer.h +++ b/source/gui/GUIRenderer.h @@ -77,7 +77,7 @@ namespace GUIRenderer namespace GUIRenderer { - void UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, const CRect& Size, int CellID, std::map &Sprites); + void UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, const CRect& Size, int CellID, std::map &Sprites); void Draw(DrawCalls &Calls, float Z); }