Make MessageQueue thread-safe

This commit is contained in:
Benau 2017-03-22 08:40:58 +08:00
parent 668b28f632
commit 2b9a84253a

View File

@ -24,6 +24,7 @@
#include "guiengine/engine.hpp" #include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp" #include "guiengine/scalable_font.hpp"
#include "guiengine/skin.hpp" #include "guiengine/skin.hpp"
#include "utils/synchronised.hpp"
#include "IGUIElement.h" #include "IGUIElement.h"
@ -88,11 +89,10 @@ public:
} // operator () } // operator ()
}; // operator() }; // operator()
// ============================================================================ // ============================================================================
/** List of all messages. */ /** List of all messages. */
std::priority_queue<Message*, std::vector<Message*>, Synchronised<std::priority_queue<Message*, std::vector<Message*>,
CompareMessages> g_all_messages; CompareMessages> > g_all_messages;
/** How long the current message has been displayed. The special value /** How long the current message has been displayed. The special value
* -1 indicates that a new message was added when the queue was empty. */ * -1 indicates that a new message was added when the queue was empty. */
@ -130,9 +130,16 @@ void createLabel(const Message *message)
* position of the message. */ * position of the message. */
void updatePosition() void updatePosition()
{ {
if (g_all_messages.empty()) return; g_all_messages.lock();
Message *last = g_all_messages.top(); bool empty = g_all_messages.getData().empty();
if (empty)
{
g_all_messages.unlock();
return;
}
Message *last = g_all_messages.getData().top();
createLabel(last); createLabel(last);
g_all_messages.unlock();
} // updatePosition } // updatePosition
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -143,13 +150,15 @@ void updatePosition()
void add(MessageType mt, const irr::core::stringw &message) void add(MessageType mt, const irr::core::stringw &message)
{ {
Message *m = new Message(mt, message); Message *m = new Message(mt, message);
if(g_all_messages.empty()) g_all_messages.lock();
if (g_all_messages.getData().empty())
{ {
// Indicate that there is a new message, which should // Indicate that there is a new message, which should
// which needs a new label etc. to be computed. // which needs a new label etc. to be computed.
g_current_display_time =-1.0f; g_current_display_time =-1.0f;
} }
g_all_messages.push(m); g_all_messages.getData().push(m);
g_all_messages.unlock();
} // add } // add
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -161,25 +170,34 @@ void add(MessageType mt, const irr::core::stringw &message)
*/ */
void update(float dt) void update(float dt)
{ {
if(g_all_messages.empty()) return; g_all_messages.lock();
bool empty = g_all_messages.getData().empty();
g_all_messages.unlock();
if (empty) return;
g_all_messages.lock();
g_current_display_time += dt; g_current_display_time += dt;
if(g_current_display_time > g_max_display_time) if (g_current_display_time > g_max_display_time)
{ {
Message *last = g_all_messages.top(); Message *last = g_all_messages.getData().top();
g_all_messages.pop(); g_all_messages.getData().pop();
delete last; delete last;
if(g_all_messages.empty()) return; if (g_all_messages.getData().empty())
{
g_all_messages.unlock();
return;
}
g_current_display_time = -1.0f; g_current_display_time = -1.0f;
} }
Message *current = g_all_messages.getData().top();
// Create new data for the display. // Create new data for the display.
if(g_current_display_time < 0) if (g_current_display_time < 0)
{ {
createLabel(g_all_messages.top()); createLabel(current);
} }
g_all_messages.unlock();
Message *current = g_all_messages.top();
GUIEngine::getSkin()->drawMessage(g_container, g_area, GUIEngine::getSkin()->drawMessage(g_container, g_area,
current->getRenderType()); current->getRenderType());
gui::ScalableFont *font = GUIEngine::getFont(); gui::ScalableFont *font = GUIEngine::getFont();