Use std::unique_ptr for message queue memory management

This commit is contained in:
Benau 2020-05-23 13:02:04 +08:00
parent acf862903d
commit cbb3863180
3 changed files with 21 additions and 54 deletions

View File

@ -838,7 +838,6 @@ namespace GUIEngine
needsUpdate.clearWithoutDeleting();
gui_messages.clear();
MessageQueue::clear();
} // clear
// ------------------------------------------------------------------------

View File

@ -25,6 +25,7 @@
#include "GlyphLayout.h"
#include <atomic>
#include <memory>
using namespace GUIEngine;
@ -32,8 +33,8 @@ namespace MessageQueue
{
// ============================================================================
/** The label widget used to show the current message. */
SkinWidgetContainer* g_container = NULL;
SkinWidgetContainer* g_static_container = NULL;
std::unique_ptr<SkinWidgetContainer> g_container;
std::unique_ptr<SkinWidgetContainer> g_static_container;
/** Stores the height of an static container to allow showing both. */
int s_msg_raise = 0;
@ -77,8 +78,6 @@ public:
}
// ------------------------------------------------------------------------
bool canBeRemoved() const { return m_display_timer < 0.0f; }
// ------------------------------------------------------------------------
virtual void remove() {}
};
@ -110,7 +109,7 @@ public:
Message(5.0f, message)
{
m_font = NULL;
m_container = g_container;
m_container = g_container.get();
m_message_type = mt;
assert(mt != MessageQueue::MT_PROGRESS);
if (mt == MessageQueue::MT_ACHIEVEMENT)
@ -190,7 +189,7 @@ public:
m_text_rect = core::recti(x, y, x + left_icon_size + total_width,
y + dim.Height);
if (m_container == g_static_container)
if (m_container == g_static_container.get())
s_msg_raise = int(dim.Height) + m_font->getHeightPerLine() / 10;
}
// ------------------------------------------------------------------------
@ -208,7 +207,7 @@ public:
if (m_font != GUIEngine::getFont())
init();
int pos_transform = 0;
if (m_container == g_container)
if (m_container == g_container.get())
pos_transform = s_msg_raise;
core::position2di raise = core::position2di(0,
irr_driver->getDevice()->getOnScreenKeyboardHeight() -
@ -218,8 +217,6 @@ public:
GUIEngine::getFont()->draw(m_gls, m_text_rect - raise,
GUIEngine::getSkin()->getColor("text::neutral"), true/*hcenter*/);
}
// ------------------------------------------------------------------------
virtual void remove() { delete this; }
}; // class TextMessage
@ -229,7 +226,7 @@ public:
StaticTextMessage(MessageQueue::MessageType mt, const core::stringw &message) :
TextMessage(mt, message)
{
m_container = g_static_container;
m_container = g_static_container.get();
m_message_type = mt;
assert(mt != MessageQueue::MT_PROGRESS);
if (mt == MessageQueue::MT_ACHIEVEMENT)
@ -252,7 +249,6 @@ public:
TextMessage::draw(dt);
m_display_timer = 9999999.9f;
}
// ------------------------------------------------------------------------
};
// ============================================================================
@ -263,7 +259,8 @@ public:
/** Used to sort messages by priority in the priority queue. Achievement
* messages (1) need to have a higher priority than friend messages
* (value 0), and errors (3) the highest priority. */
bool operator() (const Message *a, const Message *b) const
bool operator() (const std::unique_ptr<Message>& a,
const std::unique_ptr<Message>& b) const
{
return a->getMessageType() < b->getMessageType();
} // operator ()
@ -271,12 +268,12 @@ public:
// ============================================================================
/** List of all messages. */
Synchronised<std::priority_queue<Message*, std::vector<Message*>,
CompareMessages> > g_all_messages;
Synchronised<std::priority_queue<std::unique_ptr<Message>,
std::vector<std::unique_ptr<Message> >, CompareMessages> > g_all_messages;
// ============================================================================
/** The Storage for a Static Message */
StaticTextMessage* g_static_message = NULL;
std::unique_ptr<StaticTextMessage> g_static_message;
// ============================================================================
/** Add any message to the message queue.
@ -285,7 +282,7 @@ StaticTextMessage* g_static_message = NULL;
void privateAdd(Message* m)
{
g_all_messages.lock();
g_all_messages.getData().push(m);
g_all_messages.getData().emplace(std::unique_ptr<Message>(m));
g_all_messages.unlock();
} // privateAdd
@ -337,8 +334,6 @@ public:
if (g_progress.load() >= 100)
m_display_timer = -1.0f;
}
// ------------------------------------------------------------------------
virtual void remove() { delete this; }
}; // class ProgressBarMessage
@ -347,7 +342,7 @@ public:
* position of the message. */
void updatePosition()
{
if (g_static_message != 0)
if (g_static_message)
g_static_message->init();
} // updatePosition
@ -377,9 +372,7 @@ void addStatic(MessageType mt, const irr::core::stringw &message)
#ifndef SERVER_ONLY
if (GUIEngine::isNoGraphics())
return;
delete g_static_message;
g_static_message = NULL;
g_static_message = new StaticTextMessage(mt, message);
g_static_message.reset(new StaticTextMessage(mt, message));
#endif
} // addStatic
@ -396,29 +389,17 @@ void update(float dt)
if (GUIEngine::isNoGraphics())
return;
if (!g_container)
{
g_container = new SkinWidgetContainer();
}
if (!g_static_container)
{
g_static_container = new SkinWidgetContainer();
}
if (g_static_message != 0)
if (g_static_message)
g_static_message->draw(dt);
g_all_messages.lock();
if (!g_all_messages.getData().empty())
{
Message* current = g_all_messages.getData().top();
auto& current = g_all_messages.getData().top();
current->draw(dt);
if (current->canBeRemoved())
{
g_all_messages.getData().pop();
current->remove();
}
}
g_all_messages.unlock();
#endif
@ -456,32 +437,20 @@ void discardStatic()
if (GUIEngine::isNoGraphics())
return;
delete g_static_message;
g_static_message = NULL;
g_static_message.reset();
s_msg_raise = 0;
#endif
} // discardStatic
// ----------------------------------------------------------------------------
/** Clear all message, called when destroying the GUIEngine.
*/
void clear()
{
#ifndef SERVER_ONLY
delete g_static_message;
g_static_message = NULL;
#endif
}
// ----------------------------------------------------------------------------
/** Reset global variables (for clear starting in android).
*/
void resetGlobalVariables()
{
#ifndef SERVER_ONLY
g_container = NULL;
g_static_container = NULL;
g_static_message = NULL;
g_container.reset(new SkinWidgetContainer());
g_static_container.reset(new SkinWidgetContainer());
g_static_message.reset();
s_msg_raise = 0;
while (!g_all_messages.getData().empty())
g_all_messages.getData().pop();

View File

@ -49,7 +49,6 @@ namespace MessageQueue
void updatePosition();
void update(float dt);
void discardStatic();
void clear();
void resetGlobalVariables();
}; // namespace GUIEngine
#endif