forked from Mirrorlandia_minetest/minetest
Add UpdateThread and use it for minimap and mesh threads
This commit is contained in:
parent
4e28c8d3c8
commit
29dda9f356
@ -139,7 +139,7 @@ void MeshUpdateQueue::addBlock(v3s16 p, MeshMakeData *data, bool ack_block_to_se
|
|||||||
|
|
||||||
// Returned pointer must be deleted
|
// Returned pointer must be deleted
|
||||||
// Returns NULL if queue is empty
|
// Returns NULL if queue is empty
|
||||||
QueuedMeshUpdate * MeshUpdateQueue::pop()
|
QueuedMeshUpdate *MeshUpdateQueue::pop()
|
||||||
{
|
{
|
||||||
JMutexAutoLock lock(m_mutex);
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
@ -162,26 +162,17 @@ QueuedMeshUpdate * MeshUpdateQueue::pop()
|
|||||||
MeshUpdateThread
|
MeshUpdateThread
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void * MeshUpdateThread::Thread()
|
void MeshUpdateThread::enqueueUpdate(v3s16 p, MeshMakeData *data,
|
||||||
|
bool ack_block_to_server, bool urgent)
|
||||||
{
|
{
|
||||||
ThreadStarted();
|
m_queue_in.addBlock(p, data, ack_block_to_server, urgent);
|
||||||
|
deferUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
log_register_thread("MeshUpdateThread");
|
void MeshUpdateThread::doUpdate()
|
||||||
|
{
|
||||||
DSTACK(__FUNCTION_NAME);
|
QueuedMeshUpdate *q;
|
||||||
|
while ((q = m_queue_in.pop())) {
|
||||||
BEGIN_DEBUG_EXCEPTION_HANDLER
|
|
||||||
|
|
||||||
porting::setThreadName("MeshUpdateThread");
|
|
||||||
|
|
||||||
while(!StopRequested())
|
|
||||||
{
|
|
||||||
QueuedMeshUpdate *q = m_queue_in.pop();
|
|
||||||
if(q == NULL)
|
|
||||||
{
|
|
||||||
sleep_ms(3);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopeProfiler sp(g_profiler, "Client: Mesh making");
|
ScopeProfiler sp(g_profiler, "Client: Mesh making");
|
||||||
|
|
||||||
@ -196,10 +187,6 @@ void * MeshUpdateThread::Thread()
|
|||||||
|
|
||||||
delete q;
|
delete q;
|
||||||
}
|
}
|
||||||
|
|
||||||
END_DEBUG_EXCEPTION_HANDLER(errorstream)
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -230,7 +217,7 @@ Client::Client(
|
|||||||
m_nodedef(nodedef),
|
m_nodedef(nodedef),
|
||||||
m_sound(sound),
|
m_sound(sound),
|
||||||
m_event(event),
|
m_event(event),
|
||||||
m_mesh_update_thread(this),
|
m_mesh_update_thread(),
|
||||||
m_env(
|
m_env(
|
||||||
new ClientMap(this, this, control,
|
new ClientMap(this, this, control,
|
||||||
device->getSceneManager()->getRootSceneNode(),
|
device->getSceneManager()->getRootSceneNode(),
|
||||||
@ -1600,7 +1587,7 @@ void Client::addUpdateMeshTask(v3s16 p, bool ack_to_server, bool urgent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add task to queue
|
// Add task to queue
|
||||||
m_mesh_update_thread.m_queue_in.addBlock(p, data, ack_to_server, urgent);
|
m_mesh_update_thread.enqueueUpdate(p, data, ack_to_server, urgent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server, bool urgent)
|
void Client::addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server, bool urgent)
|
||||||
|
20
src/client.h
20
src/client.h
@ -113,23 +113,27 @@ struct MeshUpdateResult
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class MeshUpdateThread : public JThread
|
class MeshUpdateThread : public UpdateThread
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
MeshUpdateQueue m_queue_in;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const char *getName()
|
||||||
|
{ return "MeshUpdateThread"; }
|
||||||
|
virtual void doUpdate();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
MeshUpdateThread(IGameDef *gamedef):
|
MeshUpdateThread()
|
||||||
m_gamedef(gamedef)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void * Thread();
|
void enqueueUpdate(v3s16 p, MeshMakeData *data,
|
||||||
|
bool ack_block_to_server, bool urgent);
|
||||||
MeshUpdateQueue m_queue_in;
|
|
||||||
|
|
||||||
MutexedQueue<MeshUpdateResult> m_queue_out;
|
MutexedQueue<MeshUpdateResult> m_queue_out;
|
||||||
|
|
||||||
IGameDef *m_gamedef;
|
|
||||||
|
|
||||||
v3s16 m_camera_offset;
|
v3s16 m_camera_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -105,67 +105,31 @@ QueuedMinimapUpdate * MinimapUpdateQueue::pop()
|
|||||||
Minimap update thread
|
Minimap update thread
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void MinimapUpdateThread::Stop()
|
|
||||||
{
|
|
||||||
JThread::Stop();
|
|
||||||
|
|
||||||
// give us a nudge
|
|
||||||
m_queue_sem.Post();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MinimapUpdateThread::enqueue_Block(v3s16 pos, MinimapMapblock *data)
|
void MinimapUpdateThread::enqueue_Block(v3s16 pos, MinimapMapblock *data)
|
||||||
{
|
{
|
||||||
if (m_queue.addBlock(pos, data))
|
m_queue.addBlock(pos, data);
|
||||||
// we had to allocate a new block
|
deferUpdate();
|
||||||
m_queue_sem.Post();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MinimapUpdateThread::forceUpdate()
|
void MinimapUpdateThread::doUpdate()
|
||||||
{
|
{
|
||||||
m_queue_sem.Post();
|
while (m_queue.size()) {
|
||||||
}
|
QueuedMinimapUpdate *q = m_queue.pop();
|
||||||
|
std::map<v3s16, MinimapMapblock *>::iterator it;
|
||||||
void *MinimapUpdateThread::Thread()
|
it = m_blocks_cache.find(q->pos);
|
||||||
{
|
if (q->data) {
|
||||||
ThreadStarted();
|
m_blocks_cache[q->pos] = q->data;
|
||||||
|
} else if (it != m_blocks_cache.end()) {
|
||||||
log_register_thread("MinimapUpdateThread");
|
delete it->second;
|
||||||
|
m_blocks_cache.erase(it);
|
||||||
DSTACK(__FUNCTION_NAME);
|
}
|
||||||
|
}
|
||||||
BEGIN_DEBUG_EXCEPTION_HANDLER
|
if (data->map_invalidated) {
|
||||||
|
if (data->mode != MINIMAP_MODE_OFF) {
|
||||||
porting::setThreadName("MinimapUpdateThread");
|
getMap(data->pos, data->map_size, data->scan_height, data->radar);
|
||||||
|
data->map_invalidated = false;
|
||||||
while (!StopRequested()) {
|
|
||||||
|
|
||||||
m_queue_sem.Wait();
|
|
||||||
if (StopRequested()) break;
|
|
||||||
|
|
||||||
while (m_queue.size()) {
|
|
||||||
QueuedMinimapUpdate *q = m_queue.pop();
|
|
||||||
if (!q)
|
|
||||||
break;
|
|
||||||
std::map<v3s16, MinimapMapblock *>::iterator it;
|
|
||||||
it = m_blocks_cache.find(q->pos);
|
|
||||||
if (q->data) {
|
|
||||||
m_blocks_cache[q->pos] = q->data;
|
|
||||||
} else if (it != m_blocks_cache.end()) {
|
|
||||||
delete it->second;
|
|
||||||
m_blocks_cache.erase(it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data->map_invalidated) {
|
|
||||||
if (data->mode != MINIMAP_MODE_OFF) {
|
|
||||||
getMap(data->pos, data->map_size, data->scan_height, data->radar);
|
|
||||||
data->map_invalidated = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
END_DEBUG_EXCEPTION_HANDLER(errorstream)
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MinimapUpdateThread::~MinimapUpdateThread()
|
MinimapUpdateThread::~MinimapUpdateThread()
|
||||||
@ -177,7 +141,7 @@ MinimapUpdateThread::~MinimapUpdateThread()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MinimapPixel *MinimapUpdateThread::getMinimapPixel (v3s16 pos, s16 height, s16 &pixel_height)
|
MinimapPixel *MinimapUpdateThread::getMinimapPixel(v3s16 pos, s16 height, s16 &pixel_height)
|
||||||
{
|
{
|
||||||
pixel_height = height - MAP_BLOCKSIZE;
|
pixel_height = height - MAP_BLOCKSIZE;
|
||||||
v3s16 blockpos_max, blockpos_min, relpos;
|
v3s16 blockpos_max, blockpos_min, relpos;
|
||||||
@ -198,7 +162,7 @@ MinimapPixel *MinimapUpdateThread::getMinimapPixel (v3s16 pos, s16 height, s16 &
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
s16 MinimapUpdateThread::getAirCount (v3s16 pos, s16 height)
|
s16 MinimapUpdateThread::getAirCount(v3s16 pos, s16 height)
|
||||||
{
|
{
|
||||||
s16 air_count = 0;
|
s16 air_count = 0;
|
||||||
v3s16 blockpos_max, blockpos_min, relpos;
|
v3s16 blockpos_max, blockpos_min, relpos;
|
||||||
@ -215,7 +179,7 @@ s16 MinimapUpdateThread::getAirCount (v3s16 pos, s16 height)
|
|||||||
return air_count;
|
return air_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MinimapUpdateThread::getMap (v3s16 pos, s16 size, s16 height, bool radar)
|
void MinimapUpdateThread::getMap(v3s16 pos, s16 size, s16 height, bool radar)
|
||||||
{
|
{
|
||||||
v3s16 p = v3s16 (pos.X - size / 2, pos.Y, pos.Z - size / 2);
|
v3s16 p = v3s16 (pos.X - size / 2, pos.Y, pos.Z - size / 2);
|
||||||
|
|
||||||
@ -327,7 +291,7 @@ void Mapper::setMinimapMode(MinimapMode mode)
|
|||||||
data->scan_height = modeDefs[(int)mode * 3 + 1];
|
data->scan_height = modeDefs[(int)mode * 3 + 1];
|
||||||
data->map_size = modeDefs[(int)mode * 3 + 2];
|
data->map_size = modeDefs[(int)mode * 3 + 2];
|
||||||
data->mode = mode;
|
data->mode = mode;
|
||||||
m_minimap_update_thread->forceUpdate();
|
m_minimap_update_thread->deferUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mapper::setPos(v3s16 pos)
|
void Mapper::setPos(v3s16 pos)
|
||||||
@ -336,7 +300,7 @@ void Mapper::setPos(v3s16 pos)
|
|||||||
if (pos != data->old_pos) {
|
if (pos != data->old_pos) {
|
||||||
data->old_pos = data->pos;
|
data->old_pos = data->pos;
|
||||||
data->pos = pos;
|
data->pos = pos;
|
||||||
m_minimap_update_thread->forceUpdate();
|
m_minimap_update_thread->deferUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +96,6 @@ public:
|
|||||||
|
|
||||||
bool addBlock(v3s16 pos, MinimapMapblock *data);
|
bool addBlock(v3s16 pos, MinimapMapblock *data);
|
||||||
|
|
||||||
// blocking!!
|
|
||||||
QueuedMinimapUpdate *pop();
|
QueuedMinimapUpdate *pop();
|
||||||
|
|
||||||
u32 size()
|
u32 size()
|
||||||
@ -110,12 +109,16 @@ private:
|
|||||||
JMutex m_mutex;
|
JMutex m_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MinimapUpdateThread : public JThread
|
class MinimapUpdateThread : public UpdateThread
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
JSemaphore m_queue_sem;
|
|
||||||
MinimapUpdateQueue m_queue;
|
MinimapUpdateQueue m_queue;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const char *getName()
|
||||||
|
{ return "MinimapUpdateThread"; }
|
||||||
|
virtual void doUpdate();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MinimapUpdateThread(IrrlichtDevice *device, Client *client)
|
MinimapUpdateThread(IrrlichtDevice *device, Client *client)
|
||||||
{
|
{
|
||||||
@ -131,13 +134,10 @@ public:
|
|||||||
video::SColor getColorFromId(u16 id);
|
video::SColor getColorFromId(u16 id);
|
||||||
|
|
||||||
void enqueue_Block(v3s16 pos, MinimapMapblock *data);
|
void enqueue_Block(v3s16 pos, MinimapMapblock *data);
|
||||||
void forceUpdate();
|
|
||||||
IrrlichtDevice *device;
|
IrrlichtDevice *device;
|
||||||
Client *client;
|
Client *client;
|
||||||
video::IVideoDriver *driver;
|
video::IVideoDriver *driver;
|
||||||
ITextureSource *tsrc;
|
ITextureSource *tsrc;
|
||||||
void Stop();
|
|
||||||
void *Thread();
|
|
||||||
MinimapData *data;
|
MinimapData *data;
|
||||||
std::map<v3s16, MinimapMapblock *> m_blocks_cache;
|
std::map<v3s16, MinimapMapblock *> m_blocks_cache;
|
||||||
};
|
};
|
||||||
|
@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "../jthread/jmutex.h"
|
#include "../jthread/jmutex.h"
|
||||||
#include "../jthread/jmutexautolock.h"
|
#include "../jthread/jmutexautolock.h"
|
||||||
#include "porting.h"
|
#include "porting.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class MutexedVariable
|
class MutexedVariable
|
||||||
@ -208,5 +209,65 @@ private:
|
|||||||
MutexedQueue< GetRequest<Key, T, Caller, CallerData> > m_queue;
|
MutexedQueue< GetRequest<Key, T, Caller, CallerData> > m_queue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class UpdateThread : public JThread
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
JSemaphore m_update_sem;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void doUpdate() = 0;
|
||||||
|
virtual const char *getName() = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
UpdateThread()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
~UpdateThread()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void deferUpdate()
|
||||||
|
{
|
||||||
|
m_update_sem.Post();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stop()
|
||||||
|
{
|
||||||
|
JThread::Stop();
|
||||||
|
|
||||||
|
// give us a nudge
|
||||||
|
m_update_sem.Post();
|
||||||
|
}
|
||||||
|
|
||||||
|
void *Thread()
|
||||||
|
{
|
||||||
|
ThreadStarted();
|
||||||
|
|
||||||
|
const char *thread_name = getName();
|
||||||
|
|
||||||
|
log_register_thread(thread_name);
|
||||||
|
|
||||||
|
DSTACK(__FUNCTION_NAME);
|
||||||
|
|
||||||
|
BEGIN_DEBUG_EXCEPTION_HANDLER
|
||||||
|
|
||||||
|
porting::setThreadName(thread_name);
|
||||||
|
|
||||||
|
while (!StopRequested()) {
|
||||||
|
|
||||||
|
m_update_sem.Wait();
|
||||||
|
|
||||||
|
// Empty the queue, just in case doUpdate() is expensive
|
||||||
|
while (m_update_sem.GetValue()) m_update_sem.Wait();
|
||||||
|
|
||||||
|
if (StopRequested()) break;
|
||||||
|
|
||||||
|
doUpdate();
|
||||||
|
}
|
||||||
|
END_DEBUG_EXCEPTION_HANDLER(errorstream)
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user