diff --git a/src/lib/Application.cpp b/src/lib/Application.cpp index 9847d488..ba0d017c 100644 --- a/src/lib/Application.cpp +++ b/src/lib/Application.cpp @@ -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()); + queue->addMessageFilter(std::make_shared()); + + queue->setSendMessagesAsTasks(true); + queue->startMessageLoopThreaded(); } void Application::updateRecentProjects(const FilePath& projectSettingsFilePath) diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 7fec7da0..0578c763 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -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 diff --git a/src/lib/utility/messaging/MessageFilter.h b/src/lib/utility/messaging/MessageFilter.h new file mode 100644 index 00000000..4709a42d --- /dev/null +++ b/src/lib/utility/messaging/MessageFilter.h @@ -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 diff --git a/src/lib/utility/messaging/MessageQueue.cpp b/src/lib/utility/messaging/MessageQueue.cpp index 1204c3b3..aacf2536 100644 --- a/src/lib/utility/messaging/MessageQueue.cpp +++ b/src/lib/utility/messaging/MessageQueue.cpp @@ -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 filter) +{ + m_filters.push_back(filter); +} + void MessageQueue::pushMessage(std::shared_ptr message) { - std::lock_guard lock(m_backMessageBufferMutex); - m_backMessageBuffer->push(message); + std::lock_guard lock(m_messageBufferMutex); + m_messageBuffer.push_back(message); } void MessageQueue::processMessage(std::shared_ptr message, bool asNextTask) @@ -182,9 +188,8 @@ bool MessageQueue::loopIsRunning() const bool MessageQueue::hasMessagesQueued() const { - std::lock_guard lock(m_frontMessageBufferMutex); - std::lock_guard lock2(m_backMessageBufferMutex); - return m_backMessageBuffer->size() + m_frontMessageBuffer->size() > 0; + std::lock_guard 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(); - m_backMessageBuffer = std::make_shared(); } void MessageQueue::processMessages() { - { - std::lock_guard lock(m_frontMessageBufferMutex); - std::lock_guard lock2(m_backMessageBufferMutex); - m_backMessageBuffer.swap(m_frontMessageBuffer); - } - while (true) { std::shared_ptr message; { - std::lock_guard lock(m_frontMessageBufferMutex); + std::lock_guard lock(m_messageBufferMutex); - if (!m_frontMessageBuffer->size()) + if (!m_messageBuffer.size()) { break; } - message = m_frontMessageBuffer->front(); - m_frontMessageBuffer->pop(); + for (std::shared_ptr filter : m_filters) + { + filter->filter(&m_messageBuffer); + } + + if (!m_messageBuffer.size()) + { + break; + } + + message = m_messageBuffer.front(); + m_messageBuffer.pop_front(); } processMessage(message, false); diff --git a/src/lib/utility/messaging/MessageQueue.h b/src/lib/utility/messaging/MessageQueue.h index d9f30e64..ccab3e59 100644 --- a/src/lib/utility/messaging/MessageQueue.h +++ b/src/lib/utility/messaging/MessageQueue.h @@ -1,18 +1,22 @@ #ifndef MESSAGE_QUEUE_H #define MESSAGE_QUEUE_H +#include #include #include -#include +#include #include "utility/types.h" class MessageBase; +class MessageFilter; class MessageListenerBase; class MessageQueue { public: + typedef std::deque> MessageBufferType; + static std::shared_ptr getInstance(); ~MessageQueue(); @@ -22,6 +26,8 @@ public: MessageListenerBase* getListenerById(const uint id) const; + void addMessageFilter(std::shared_ptr filter); + void pushMessage(std::shared_ptr message); void processMessage(std::shared_ptr message, bool asNextTask); @@ -35,8 +41,6 @@ public: void setSendMessagesAsTasks(bool sendMessagesAsTasks); private: - typedef std::queue> MessageBufferType; - static std::shared_ptr s_instance; MessageQueue(); @@ -47,9 +51,9 @@ private: void sendMessage(std::shared_ptr message); void sendMessageAsTask(std::shared_ptr message, bool asNextTask) const; - std::shared_ptr m_frontMessageBuffer; - std::shared_ptr m_backMessageBuffer; + MessageBufferType m_messageBuffer; std::vector m_listeners; + std::vector> 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; diff --git a/src/lib/utility/messaging/filter_types/MessageFilterFocusInOut.h b/src/lib/utility/messaging/filter_types/MessageFilterFocusInOut.h new file mode 100644 index 00000000..159292bc --- /dev/null +++ b/src/lib/utility/messaging/filter_types/MessageFilterFocusInOut.h @@ -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(message)->tokenIds == dynamic_cast(it->get())->tokenIds) + { + messageBuffer->erase(it); + messageBuffer->pop_front(); + return; + } + } + } + } +}; + +#endif // MESSAGE_FILTER_FOCUS_IN_OUT_H diff --git a/src/lib/utility/messaging/filter_types/MessageFilterSearchAutocomplete.h b/src/lib/utility/messaging/filter_types/MessageFilterSearchAutocomplete.h new file mode 100644 index 00000000..0eb54271 --- /dev/null +++ b/src/lib/utility/messaging/filter_types/MessageFilterSearchAutocomplete.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