diff --git a/src/minimap.cpp b/src/minimap.cpp index 61960ca1..753468c3 100644 --- a/src/minimap.cpp +++ b/src/minimap.cpp @@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "minimap.h" #include "logoutputbuffer.h" #include "jthread/jmutexautolock.h" +#include "jthread/jsemaphore.h" #include "clientmap.h" #include "settings.h" #include "nodedef.h" @@ -47,16 +48,15 @@ MinimapUpdateQueue::~MinimapUpdateQueue() { JMutexAutoLock lock(m_mutex); - for (std::vector::iterator + for (std::list::iterator i = m_queue.begin(); - i != m_queue.end(); i++) - { + i != m_queue.end(); ++i) { QueuedMinimapUpdate *q = *i; delete q; } } -void MinimapUpdateQueue::addBlock(v3s16 pos, MinimapMapblock *data) +bool MinimapUpdateQueue::addBlock(v3s16 pos, MinimapMapblock *data) { DSTACK(__FUNCTION_NAME); @@ -66,15 +66,14 @@ void MinimapUpdateQueue::addBlock(v3s16 pos, MinimapMapblock *data) Find if block is already in queue. If it is, update the data and quit. */ - for (std::vector::iterator + for (std::list::iterator i = m_queue.begin(); - i != m_queue.end(); i++) - { + i != m_queue.end(); ++i) { QueuedMinimapUpdate *q = *i; if (q->pos == pos) { delete q->data; q->data = data; - return; + return false; } } @@ -85,16 +84,16 @@ void MinimapUpdateQueue::addBlock(v3s16 pos, MinimapMapblock *data) q->pos = pos; q->data = data; m_queue.push_back(q); + return true; } QueuedMinimapUpdate * MinimapUpdateQueue::pop() { JMutexAutoLock lock(m_mutex); - for (std::vector::iterator + for (std::list::iterator i = m_queue.begin(); - i != m_queue.end(); i++) - { + i != m_queue.end(); i++) { QueuedMinimapUpdate *q = *i; m_queue.erase(i); return q; @@ -106,6 +105,22 @@ QueuedMinimapUpdate * MinimapUpdateQueue::pop() Minimap update thread */ +void MinimapUpdateThread::Stop() +{ + JThread::Stop(); + + // give us a nudge + m_queue_sem.Post(); +} + +void MinimapUpdateThread::enqueue_Block(v3s16 pos, MinimapMapblock *data) +{ + if (m_queue.addBlock(pos, data)) + // we had to allocate a new block + m_queue_sem.Post(); +} + + void *MinimapUpdateThread::Thread() { ThreadStarted(); @@ -120,8 +135,13 @@ void *MinimapUpdateThread::Thread() while (!StopRequested()) { + m_queue_sem.Wait(); + if (StopRequested()) break; + while (m_queue.size()) { QueuedMinimapUpdate *q = m_queue.pop(); + if (!q) + break; std::map::iterator it; it = m_blocks_cache.find(q->pos); if (q->data) { @@ -138,7 +158,6 @@ void *MinimapUpdateThread::Thread() data->map_invalidated = false; } } - // sleep_ms(10); } END_DEBUG_EXCEPTION_HANDLER(errorstream) @@ -266,7 +285,7 @@ Mapper::~Mapper() void Mapper::addBlock (v3s16 pos, MinimapMapblock *data) { - m_minimap_update_thread->m_queue.addBlock(pos, data); + m_minimap_update_thread->enqueue_Block(pos, data); } MinimapMode Mapper::getMinimapMode() diff --git a/src/minimap.h b/src/minimap.h index ebb74c4f..1794da19 100644 --- a/src/minimap.h +++ b/src/minimap.h @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "client.h" #include "voxel.h" #include "jthread/jmutex.h" +#include "jthread/jsemaphore.h" #include #include #include @@ -93,8 +94,9 @@ public: ~MinimapUpdateQueue(); - void addBlock(v3s16 pos, MinimapMapblock *data); + bool addBlock(v3s16 pos, MinimapMapblock *data); + // blocking!! QueuedMinimapUpdate *pop(); u32 size() @@ -104,13 +106,15 @@ public: } private: - std::vector m_queue; + std::list m_queue; JMutex m_mutex; }; class MinimapUpdateThread : public JThread { private: + JSemaphore m_queue_sem; + MinimapUpdateQueue m_queue; public: MinimapUpdateThread(IrrlichtDevice *device, Client *client) @@ -124,13 +128,16 @@ public: MinimapPixel *getMinimapPixel (v3s16 pos, s16 height, s16 &pixel_height); s16 getAirCount (v3s16 pos, s16 height); video::SColor getColorFromId(u16 id); + + void enqueue_Block(v3s16 pos, MinimapMapblock *data); + IrrlichtDevice *device; Client *client; video::IVideoDriver *driver; ITextureSource *tsrc; + void Stop(); void *Thread(); MinimapData *data; - MinimapUpdateQueue m_queue; std::map m_blocks_cache; };