utility: Added MessageFilter API to messaging

* filter out focus in and out messages if both in queue
* filter out search autocomplete when multiple in queue
This commit is contained in:
Eberhard Graether
2017-05-14 19:39:05 +02:00
parent 6193ae9209
commit 3dfc0cb341
7 changed files with 118 additions and 26 deletions
+9 -2
View File
@@ -3,6 +3,8 @@
#include "utility/interprocess/SharedMemoryGarbageCollector.h"
#include "utility/logging/logging.h"
#include "utility/logging/LogManager.h"
#include "utility/messaging/filter_types/MessageFilterFocusInOut.h"
#include "utility/messaging/filter_types/MessageFilterSearchAutocomplete.h"
#include "utility/messaging/MessageQueue.h"
#include "utility/messaging/type/MessageStatus.h"
#include "utility/messaging/type/MessageShowStartScreen.h"
@@ -307,8 +309,13 @@ void Application::handleMessage(MessageSwitchColorScheme* message)
void Application::startMessagingAndScheduling()
{
TaskScheduler::getInstance()->startSchedulerLoopThreaded();
MessageQueue::getInstance()->setSendMessagesAsTasks(true);
MessageQueue::getInstance()->startMessageLoopThreaded();
MessageQueue* queue = MessageQueue::getInstance().get();
queue->addMessageFilter(std::make_shared<MessageFilterFocusInOut>());
queue->addMessageFilter(std::make_shared<MessageFilterSearchAutocomplete>());
queue->setSendMessagesAsTasks(true);
queue->startMessageLoopThreaded();
}
void Application::updateRecentProjects(const FilePath& projectSettingsFilePath)
+4
View File
@@ -329,6 +329,9 @@ add_files(
utility/math/Vector4.h
utility/math/VectorBase.h
utility/messaging/filter_types/MessageFilterFocusInOut.h
utility/messaging/filter_types/MessageFilterSearchAutocomplete.h
utility/messaging/type/MessageActivateAll.h
utility/messaging/type/MessageActivateBookmark.h
utility/messaging/type/MessageActivateEdge.h
@@ -405,6 +408,7 @@ add_files(
utility/messaging/Message.h
utility/messaging/MessageBase.h
utility/messaging/MessageFilter.h
utility/messaging/MessageInterruptTasksCounter.cpp
utility/messaging/MessageInterruptTasksCounter.h
utility/messaging/MessageListener.h
+14
View File
@@ -0,0 +1,14 @@
#ifndef MESSAGE_FILTER_H
#define MESSAGE_FILTER_H
#include "utility/messaging/MessageQueue.h"
class MessageFilter
{
public:
virtual ~MessageFilter() {}
virtual void filter(MessageQueue::MessageBufferType* messageBuffer) = 0;
};
#endif // MESSAGE_FILTER_H
+24 -17
View File
@@ -5,6 +5,7 @@
#include "utility/logging/logging.h"
#include "utility/messaging/MessageBase.h"
#include "utility/messaging/MessageFilter.h"
#include "utility/messaging/MessageListenerBase.h"
#include "utility/scheduling/TaskGroupParallel.h"
#include "utility/scheduling/TaskLambda.h"
@@ -75,10 +76,15 @@ MessageListenerBase* MessageQueue::getListenerById(const uint id) const
return nullptr;
}
void MessageQueue::addMessageFilter(std::shared_ptr<MessageFilter> filter)
{
m_filters.push_back(filter);
}
void MessageQueue::pushMessage(std::shared_ptr<MessageBase> message)
{
std::lock_guard<std::mutex> lock(m_backMessageBufferMutex);
m_backMessageBuffer->push(message);
std::lock_guard<std::mutex> lock(m_messageBufferMutex);
m_messageBuffer.push_back(message);
}
void MessageQueue::processMessage(std::shared_ptr<MessageBase> message, bool asNextTask)
@@ -182,9 +188,8 @@ bool MessageQueue::loopIsRunning() const
bool MessageQueue::hasMessagesQueued() const
{
std::lock_guard<std::mutex> lock(m_frontMessageBufferMutex);
std::lock_guard<std::mutex> lock2(m_backMessageBufferMutex);
return m_backMessageBuffer->size() + m_frontMessageBuffer->size() > 0;
std::lock_guard<std::mutex> lock(m_messageBufferMutex);
return m_messageBuffer.size() > 0;
}
void MessageQueue::setSendMessagesAsTasks(bool sendMessagesAsTasks)
@@ -201,31 +206,33 @@ MessageQueue::MessageQueue()
, m_threadIsRunning(false)
, m_sendMessagesAsTasks(false)
{
m_frontMessageBuffer = std::make_shared<MessageBufferType>();
m_backMessageBuffer = std::make_shared<MessageBufferType>();
}
void MessageQueue::processMessages()
{
{
std::lock_guard<std::mutex> lock(m_frontMessageBufferMutex);
std::lock_guard<std::mutex> lock2(m_backMessageBufferMutex);
m_backMessageBuffer.swap(m_frontMessageBuffer);
}
while (true)
{
std::shared_ptr<MessageBase> message;
{
std::lock_guard<std::mutex> lock(m_frontMessageBufferMutex);
std::lock_guard<std::mutex> lock(m_messageBufferMutex);
if (!m_frontMessageBuffer->size())
if (!m_messageBuffer.size())
{
break;
}
message = m_frontMessageBuffer->front();
m_frontMessageBuffer->pop();
for (std::shared_ptr<MessageFilter> filter : m_filters)
{
filter->filter(&m_messageBuffer);
}
if (!m_messageBuffer.size())
{
break;
}
message = m_messageBuffer.front();
m_messageBuffer.pop_front();
}
processMessage(message, false);
+10 -7
View File
@@ -1,18 +1,22 @@
#ifndef MESSAGE_QUEUE_H
#define MESSAGE_QUEUE_H
#include <deque>
#include <memory>
#include <mutex>
#include <queue>
#include <vector>
#include "utility/types.h"
class MessageBase;
class MessageFilter;
class MessageListenerBase;
class MessageQueue
{
public:
typedef std::deque<std::shared_ptr<MessageBase>> MessageBufferType;
static std::shared_ptr<MessageQueue> getInstance();
~MessageQueue();
@@ -22,6 +26,8 @@ public:
MessageListenerBase* getListenerById(const uint id) const;
void addMessageFilter(std::shared_ptr<MessageFilter> filter);
void pushMessage(std::shared_ptr<MessageBase> message);
void processMessage(std::shared_ptr<MessageBase> message, bool asNextTask);
@@ -35,8 +41,6 @@ public:
void setSendMessagesAsTasks(bool sendMessagesAsTasks);
private:
typedef std::queue<std::shared_ptr<MessageBase>> MessageBufferType;
static std::shared_ptr<MessageQueue> s_instance;
MessageQueue();
@@ -47,9 +51,9 @@ private:
void sendMessage(std::shared_ptr<MessageBase> message);
void sendMessageAsTask(std::shared_ptr<MessageBase> message, bool asNextTask) const;
std::shared_ptr<MessageBufferType> m_frontMessageBuffer;
std::shared_ptr<MessageBufferType> m_backMessageBuffer;
MessageBufferType m_messageBuffer;
std::vector<MessageListenerBase*> m_listeners;
std::vector<std::shared_ptr<MessageFilter>> m_filters;
size_t m_currentListenerIndex;
size_t m_listenersLength;
@@ -57,8 +61,7 @@ private:
bool m_loopIsRunning;
bool m_threadIsRunning;
mutable std::mutex m_frontMessageBufferMutex;
mutable std::mutex m_backMessageBufferMutex;
mutable std::mutex m_messageBufferMutex;
mutable std::mutex m_listenersMutex;
mutable std::mutex m_loopMutex;
mutable std::mutex m_threadMutex;
@@ -0,0 +1,30 @@
#ifndef MESSAGE_FILTER_FOCUS_IN_OUT_H
#define MESSAGE_FILTER_FOCUS_IN_OUT_H
#include "utility/messaging/MessageFilter.h"
#include "utility/messaging/type/MessageFocusIn.h"
#include "utility/messaging/type/MessageFocusOut.h"
class MessageFilterFocusInOut
: public MessageFilter
{
void filter(MessageQueue::MessageBufferType* messageBuffer) override
{
MessageBase* message = messageBuffer->front().get();
if (message->getType() == MessageFocusIn::getStaticType())
{
for (auto it = messageBuffer->begin() + 1; it != messageBuffer->end(); it++)
{
if ((*it)->getType() == MessageFocusOut::getStaticType() &&
dynamic_cast<MessageFocusIn*>(message)->tokenIds == dynamic_cast<MessageFocusOut*>(it->get())->tokenIds)
{
messageBuffer->erase(it);
messageBuffer->pop_front();
return;
}
}
}
}
};
#endif // MESSAGE_FILTER_FOCUS_IN_OUT_H
@@ -0,0 +1,27 @@
#ifndef MESSAGE_FILTER_SEARCH_AUTOCOMPLETE_H
#define MESSAGE_FILTER_SEARCH_AUTOCOMPLETE_H
#include "utility/messaging/MessageFilter.h"
#include "utility/messaging/type/MessageSearchAutocomplete.h"
class MessageFilterSearchAutocomplete
: public MessageFilter
{
void filter(MessageQueue::MessageBufferType* messageBuffer) override
{
MessageBase* message = messageBuffer->front().get();
if (message->getType() == MessageSearchAutocomplete::getStaticType())
{
for (auto it = messageBuffer->begin() + 1; it != messageBuffer->end(); it++)
{
if ((*it)->getType() == MessageSearchAutocomplete::getStaticType())
{
messageBuffer->pop_front();
return;
}
}
}
}
};
#endif // MESSAGE_FILTER_SEARCH_AUTOCOMPLETE_H