forked from organicmaps/organicmaps-tmp
[drape] cross-thread communication channel
This commit is contained in:
parent
dee5053a23
commit
d5eaaf4e01
8 changed files with 233 additions and 0 deletions
20
drape_frontend/message.cpp
Normal file
20
drape_frontend/message.cpp
Normal file
|
@ -0,0 +1,20 @@
|
|||
#include "message.hpp"
|
||||
|
||||
#include "../base/assert.hpp"
|
||||
|
||||
namespace df
|
||||
{
|
||||
Message::Message()
|
||||
: m_type(Unknown) {}
|
||||
|
||||
Message::Type Message::GetType() const
|
||||
{
|
||||
ASSERT(m_type != Unknown, ());
|
||||
return m_type;
|
||||
}
|
||||
|
||||
void Message::SetType(Type t)
|
||||
{
|
||||
m_type = t;
|
||||
}
|
||||
}
|
30
drape_frontend/message.hpp
Normal file
30
drape_frontend/message.hpp
Normal file
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
namespace df
|
||||
{
|
||||
class Message
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
// in perfect world GetType never return this type
|
||||
// for this you need call SetType on subclass constructor
|
||||
Unknown,
|
||||
DropTile,
|
||||
DropCoverage,
|
||||
UpdateCoverage,
|
||||
Resize,
|
||||
TaskFinish
|
||||
};
|
||||
|
||||
Message();
|
||||
virtual ~Message() {}
|
||||
Type GetType() const;
|
||||
|
||||
protected:
|
||||
void SetType(Type t);
|
||||
|
||||
private:
|
||||
Type m_type;
|
||||
};
|
||||
}
|
34
drape_frontend/message_acceptor.cpp
Normal file
34
drape_frontend/message_acceptor.cpp
Normal file
|
@ -0,0 +1,34 @@
|
|||
#include "message_acceptor.hpp"
|
||||
|
||||
#include "message.hpp"
|
||||
|
||||
namespace df
|
||||
{
|
||||
void MessageAcceptor::ProcessSingleMessage(bool waitMessage)
|
||||
{
|
||||
Message * message = m_messageQueue.PopMessage(waitMessage);
|
||||
if (message == NULL)
|
||||
return;
|
||||
|
||||
AcceptMessage(message);
|
||||
delete message;
|
||||
}
|
||||
|
||||
void MessageAcceptor::PostMessage(Message * message)
|
||||
{
|
||||
m_messageQueue.PushMessage(message);
|
||||
}
|
||||
|
||||
void MessageAcceptor::CloseQueue()
|
||||
{
|
||||
m_messageQueue.CancelWait();
|
||||
ClearQueue();
|
||||
}
|
||||
|
||||
void MessageAcceptor::ClearQueue()
|
||||
{
|
||||
Message * message;
|
||||
while ((message = m_messageQueue.PopMessage(false)) != NULL)
|
||||
delete message;
|
||||
}
|
||||
}
|
27
drape_frontend/message_acceptor.hpp
Normal file
27
drape_frontend/message_acceptor.hpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include "message_queue.hpp"
|
||||
|
||||
namespace df
|
||||
{
|
||||
class Message;
|
||||
|
||||
class MessageAcceptor
|
||||
{
|
||||
protected:
|
||||
virtual void AcceptMessage(Message * message) = 0;
|
||||
|
||||
/// Must be called by subclass on message target thread
|
||||
void ProcessSingleMessage(bool waitMessage);
|
||||
void CloseQueue();
|
||||
|
||||
private:
|
||||
friend class ThreadsCommutator;
|
||||
|
||||
void PostMessage(Message * message);
|
||||
void ClearQueue();
|
||||
|
||||
private:
|
||||
MessageQueue m_messageQueue;
|
||||
};
|
||||
}
|
45
drape_frontend/message_queue.cpp
Normal file
45
drape_frontend/message_queue.cpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include "message_queue.hpp"
|
||||
|
||||
#include "../base/assert.hpp"
|
||||
|
||||
namespace df
|
||||
{
|
||||
Message * MessageQueue::PopMessage(bool waitMessage)
|
||||
{
|
||||
threads::ConditionGuard guard(m_condition);
|
||||
|
||||
if (waitMessage)
|
||||
WaitMessage();
|
||||
|
||||
/// even waitNonEmpty == true m_messages can be empty after WaitMessage call
|
||||
/// if application preparing to close and CancelWait been called
|
||||
if (m_messages.empty())
|
||||
return NULL;
|
||||
|
||||
Message * msg = m_messages.front();
|
||||
m_messages.pop_front();
|
||||
return msg;
|
||||
}
|
||||
|
||||
void MessageQueue::PushMessage(Message * message)
|
||||
{
|
||||
threads::ConditionGuard guard(m_condition);
|
||||
|
||||
bool wasEmpty = m_messages.empty();
|
||||
m_messages.push_back(message);
|
||||
|
||||
if (wasEmpty)
|
||||
guard.Signal();
|
||||
}
|
||||
|
||||
void MessageQueue::WaitMessage()
|
||||
{
|
||||
if (m_messages.empty())
|
||||
m_condition.Wait();
|
||||
}
|
||||
|
||||
void MessageQueue::CancelWait()
|
||||
{
|
||||
m_condition.Signal();
|
||||
}
|
||||
}
|
28
drape_frontend/message_queue.hpp
Normal file
28
drape_frontend/message_queue.hpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#include "message.hpp"
|
||||
|
||||
#include "../base/condition.hpp"
|
||||
|
||||
#include "../std/list.hpp"
|
||||
|
||||
namespace df
|
||||
{
|
||||
class MessageQueue
|
||||
{
|
||||
public:
|
||||
MessageQueue();
|
||||
|
||||
/// if queue is empty than return NULL
|
||||
Message * PopMessage(bool waitMessage);
|
||||
void PushMessage(Message * message);
|
||||
void CancelWait();
|
||||
|
||||
private:
|
||||
void WaitMessage();
|
||||
|
||||
private:
|
||||
threads::Condition m_condition;
|
||||
list<Message *> m_messages;
|
||||
};
|
||||
}
|
23
drape_frontend/threads_commutator.cpp
Normal file
23
drape_frontend/threads_commutator.cpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
#include "threads_commutator.hpp"
|
||||
|
||||
#include "message_acceptor.hpp"
|
||||
|
||||
#include "../base/assert.hpp"
|
||||
|
||||
namespace df
|
||||
{
|
||||
void ThreadsCommutator::RegisterThread(ThreadName name, MessageAcceptor * acceptor)
|
||||
{
|
||||
ASSERT(m_acceptors.find(name) == m_acceptors.end(), ());
|
||||
m_acceptors[name] = acceptor;
|
||||
}
|
||||
|
||||
void ThreadsCommutator::PostMessage(ThreadName name, Message * message)
|
||||
{
|
||||
acceptors_map_t::iterator it = m_acceptors.find(name);
|
||||
ASSERT(it != m_acceptors.end(), ());
|
||||
if (it != m_acceptors.end())
|
||||
it->second->AcceptMessage(message);
|
||||
}
|
||||
}
|
||||
|
26
drape_frontend/threads_commutator.hpp
Normal file
26
drape_frontend/threads_commutator.hpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#pragma once
|
||||
|
||||
#include "../std/map.hpp"
|
||||
|
||||
namespace df
|
||||
{
|
||||
class Message;
|
||||
class MessageAcceptor;
|
||||
|
||||
class ThreadsCommutator
|
||||
{
|
||||
public:
|
||||
enum ThreadName
|
||||
{
|
||||
RenderThread,
|
||||
ResourceUploadThread
|
||||
};
|
||||
|
||||
void RegisterThread(ThreadName name, MessageAcceptor * acceptor);
|
||||
void PostMessage(ThreadName name, Message * message);
|
||||
|
||||
private:
|
||||
typedef map<ThreadName, MessageAcceptor *> acceptors_map_t;
|
||||
acceptors_map_t m_acceptors;
|
||||
};
|
||||
}
|
Loading…
Add table
Reference in a new issue