diff --git a/src/lib/Application.cpp b/src/lib/Application.cpp index 01de79c4..99badb5a 100644 --- a/src/lib/Application.cpp +++ b/src/lib/Application.cpp @@ -3,6 +3,7 @@ #include "utility/logging/logging.h" #include "utility/messaging/MessageQueue.h" #include "utility/messaging/type/MessageActivateTokens.h" +#include "utility/messaging/type/MessageStatus.h" #include "utility/scheduling/TaskScheduler.h" #include "component/view/MainView.h" @@ -40,19 +41,22 @@ std::shared_ptr Application::create(ViewFactory* viewFactory) Application::Application() { - MessageQueue::getInstance()->startMessageLoopThreaded(); TaskScheduler::getInstance()->startSchedulerLoopThreaded(); + MessageQueue::getInstance()->setSendMessagesAsTasks(true); + MessageQueue::getInstance()->startMessageLoopThreaded(); } Application::~Application() { - TaskScheduler::getInstance()->stopSchedulerLoop(); MessageQueue::getInstance()->stopMessageLoop(); + TaskScheduler::getInstance()->stopSchedulerLoop(); m_mainView->saveLayout(); } void Application::loadProject(const std::string& projectSettingsFilePath) { + MessageStatus("Loading Project: " + projectSettingsFilePath).dispatch(); + m_project = Project::create(m_storageAccessProxy.get()); m_project->loadProjectSettings(projectSettingsFilePath); @@ -61,6 +65,8 @@ void Application::loadProject(const std::string& projectSettingsFilePath) void Application::loadSource(const std::string& sourceDirectoryPath) { + MessageStatus("Loading Source: " + sourceDirectoryPath).dispatch(); + m_project = Project::create(m_storageAccessProxy.get()); m_project->clearProjectSettings(); @@ -70,6 +76,8 @@ void Application::loadSource(const std::string& sourceDirectoryPath) void Application::reloadProject() { + MessageStatus("Refreshing Project").dispatch(); + m_project->parseCode(); } diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 37da7fe7..2d312ada 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -239,7 +239,6 @@ add_files( utility/messaging/type/MessageActivateTokenLocation.h utility/messaging/type/MessageActivateTokens.h utility/messaging/type/MessageAutoRefreshChanged.h - utility/messaging/type/MessageError.h utility/messaging/type/MessageFind.h utility/messaging/type/MessageFinishedParsing.h utility/messaging/type/MessageGraphNodeExpand.h @@ -264,6 +263,10 @@ add_files( utility/messaging/MessageQueue.cpp utility/messaging/MessageQueue.h + utility/scheduling/LambdaTask.cpp + utility/scheduling/LambdaTask.h + utility/scheduling/SimpleTask.cpp + utility/scheduling/SimpleTask.h utility/scheduling/Task.cpp utility/scheduling/Task.h utility/scheduling/TaskGroup.cpp diff --git a/src/lib/component/ComponentManager.cpp b/src/lib/component/ComponentManager.cpp index 14b7ad54..a7baa2d6 100644 --- a/src/lib/component/ComponentManager.cpp +++ b/src/lib/component/ComponentManager.cpp @@ -23,12 +23,6 @@ ComponentManager::~ComponentManager() void ComponentManager::setup(ViewLayout* viewLayout) { - std::shared_ptr graphComponent = m_componentFactory->createGraphComponent(viewLayout); - m_components.push_back(graphComponent); - - std::shared_ptr codeComponent = m_componentFactory->createCodeComponent(viewLayout); - m_components.push_back(codeComponent); - std::shared_ptr compositeView = m_componentFactory->getViewFactory()->createCompositeView(viewLayout, CompositeView::DIRECTION_HORIZONTAL); m_compositeViews.push_back(compositeView); @@ -42,6 +36,12 @@ void ComponentManager::setup(ViewLayout* viewLayout) std::shared_ptr searchComponent = m_componentFactory->createSearchComponent(compositeView.get()); m_components.push_back(searchComponent); + std::shared_ptr graphComponent = m_componentFactory->createGraphComponent(viewLayout); + m_components.push_back(graphComponent); + + std::shared_ptr codeComponent = m_componentFactory->createCodeComponent(viewLayout); + m_components.push_back(codeComponent); + std::shared_ptr statusBarComponent = m_componentFactory->createStatusBarComponent(viewLayout); m_components.push_back(statusBarComponent); } diff --git a/src/lib/component/controller/StatusBarController.cpp b/src/lib/component/controller/StatusBarController.cpp index 823af47d..0443c204 100644 --- a/src/lib/component/controller/StatusBarController.cpp +++ b/src/lib/component/controller/StatusBarController.cpp @@ -1,19 +1,10 @@ #include "component/controller/StatusBarController.h" -#include -#include - #include "utility/logging/logging.h" #include "component/view/StatusBarView.h" StatusBarController::StatusBarController() - : MessageListener(true) - , MessageListener(true) - , MessageListener(true) - , MessageListener(true) - , MessageListener(true) - , MessageListener(true) { } @@ -26,42 +17,9 @@ StatusBarView* StatusBarController::getView() return Controller::getView(); } -void StatusBarController::handleMessage(MessageFinishedParsing* message) -{ - std::stringstream ss; - ss << "Parsing Finished: "; - ss << message->fileCount << "/" << message->totalFileCount << " files, "; - ss << std::setprecision(2) << std::fixed << message->parseTime << " seconds, "; - ss << message->errorCount << " error(s)"; - - bool hasErrors = message->errorCount > 0; - - setStatus(ss.str(), hasErrors); -} - void StatusBarController::handleMessage(MessageStatus* message) { - setStatus(message->status); -} - -void StatusBarController::handleMessage(MessageError* message) -{ - setStatus(message->error, true); -} - -void StatusBarController::handleMessage(MessageLoadProject* message) -{ - setStatus("Loading Project: " + message->projectSettingsFilePath); -} - -void StatusBarController::handleMessage(MessageLoadSource* message) -{ - setStatus("Loading Source: " + message->sourceDirectoryPath); -} - -void StatusBarController::handleMessage(MessageRefresh* message) -{ - setStatus("Refreshing Project"); + setStatus(message->status, message->isError); } void StatusBarController::setStatus(const std::string& status, bool isError) diff --git a/src/lib/component/controller/StatusBarController.h b/src/lib/component/controller/StatusBarController.h index 4fa8efe3..9c6ee187 100644 --- a/src/lib/component/controller/StatusBarController.h +++ b/src/lib/component/controller/StatusBarController.h @@ -6,22 +6,12 @@ #include "component/controller/Controller.h" #include "utility/messaging/MessageListener.h" -#include "utility/messaging/type/MessageError.h" -#include "utility/messaging/type/MessageFinishedParsing.h" -#include "utility/messaging/type/MessageLoadProject.h" -#include "utility/messaging/type/MessageLoadSource.h" -#include "utility/messaging/type/MessageRefresh.h" #include "utility/messaging/type/MessageStatus.h" class StatusBarView; class StatusBarController : public Controller - , public MessageListener - , public MessageListener - , public MessageListener - , public MessageListener - , public MessageListener , public MessageListener { public: @@ -31,14 +21,9 @@ public: StatusBarView* getView(); private: - virtual void handleMessage(MessageError* message); - virtual void handleMessage(MessageFinishedParsing* message); - virtual void handleMessage(MessageLoadProject* message); - virtual void handleMessage(MessageLoadSource* message); - virtual void handleMessage(MessageRefresh* message); virtual void handleMessage(MessageStatus* message); - void setStatus(const std::string& status, bool isError = false); + void setStatus(const std::string& status, bool isError); }; #endif // STATUS_BAR_CONTROLLER_H diff --git a/src/lib/component/controller/UndoRedoController.cpp b/src/lib/component/controller/UndoRedoController.cpp index 68705eb0..2a9c708b 100644 --- a/src/lib/component/controller/UndoRedoController.cpp +++ b/src/lib/component/controller/UndoRedoController.cpp @@ -4,10 +4,7 @@ #include "utility/logging/logging.h" UndoRedoController::UndoRedoController() - : MessageListener(true) - , MessageListener(true) - , MessageListener(true) - , m_lastCommand(nullptr) + : m_lastCommand(nullptr) { } diff --git a/src/lib/utility/messaging/Message.h b/src/lib/utility/messaging/Message.h index d41f9b21..86cef81a 100644 --- a/src/lib/utility/messaging/Message.h +++ b/src/lib/utility/messaging/Message.h @@ -21,7 +21,7 @@ public: return MessageType::getStaticType(); } - void dispatch() + virtual void dispatch() { std::shared_ptr message = std::make_shared(*dynamic_cast(this)); MessageQueue::getInstance()->pushMessage(message); diff --git a/src/lib/utility/messaging/MessageBase.h b/src/lib/utility/messaging/MessageBase.h index e1c0a65a..8cdb5a92 100644 --- a/src/lib/utility/messaging/MessageBase.h +++ b/src/lib/utility/messaging/MessageBase.h @@ -10,9 +10,15 @@ public: { UndoType_Normal, UndoType_Redo, - UndoType_Undo, + UndoType_Undo }; - MessageBase() : UndoRedoType(UndoType_Normal){}; + + MessageBase() + : UndoRedoType(UndoType_Normal) + , m_sendAsTask(true) + { + } + virtual ~MessageBase() { } @@ -20,8 +26,20 @@ public: virtual std::string getType() const = 0; virtual void dispatch() = 0; + bool sendAsTask() const + { + return m_sendAsTask; + } + + void setSendAsTask(bool sendAsTask) + { + m_sendAsTask = sendAsTask; + } + UndoType UndoRedoType; +private: + bool m_sendAsTask; }; #endif // MESSAGE_BASE_H diff --git a/src/lib/utility/messaging/MessageListener.h b/src/lib/utility/messaging/MessageListener.h index a7aadc0f..73efae4a 100644 --- a/src/lib/utility/messaging/MessageListener.h +++ b/src/lib/utility/messaging/MessageListener.h @@ -11,8 +11,7 @@ template class MessageListener: public MessageListenerBase { public: - MessageListener(bool toFront = false) - : MessageListenerBase(toFront) + MessageListener() { } diff --git a/src/lib/utility/messaging/MessageListenerBase.h b/src/lib/utility/messaging/MessageListenerBase.h index 233fbda3..b7535682 100644 --- a/src/lib/utility/messaging/MessageListenerBase.h +++ b/src/lib/utility/messaging/MessageListenerBase.h @@ -9,9 +9,9 @@ class MessageListenerBase { public: - MessageListenerBase(bool toFront) + MessageListenerBase() { - MessageQueue::getInstance()->registerListener(this, toFront); + MessageQueue::getInstance()->registerListener(this); } virtual ~MessageListenerBase() diff --git a/src/lib/utility/messaging/MessageQueue.cpp b/src/lib/utility/messaging/MessageQueue.cpp index c4299906..8922df5c 100644 --- a/src/lib/utility/messaging/MessageQueue.cpp +++ b/src/lib/utility/messaging/MessageQueue.cpp @@ -6,6 +6,8 @@ #include "utility/logging/logging.h" #include "utility/messaging/MessageBase.h" #include "utility/messaging/MessageListenerBase.h" +#include "utility/scheduling/LambdaTask.h" +#include "utility/scheduling/TaskGroupSequential.h" std::shared_ptr MessageQueue::getInstance() { @@ -17,20 +19,10 @@ std::shared_ptr MessageQueue::getInstance() return s_instance; } -void MessageQueue::registerListener(MessageListenerBase* listener, bool toFront) +void MessageQueue::registerListener(MessageListenerBase* listener) { std::lock_guard lock(m_listenersMutex); - - if (toFront) - { - m_listeners.insert(m_listeners.begin(), listener); - m_listenersLength++; - m_currentListenerIndex++; - } - else - { - m_listeners.push_back(listener); - } + m_listeners.push_back(listener); } void MessageQueue::unregisterListener(MessageListenerBase* listener) @@ -156,6 +148,11 @@ bool MessageQueue::hasMessagesQueued() const return m_backMessageBuffer->size() + m_frontMessageBuffer->size() > 0; } +void MessageQueue::setSendMessagesAsTasks(bool sendMessagesAsTasks) +{ + m_sendMessagesAsTasks = sendMessagesAsTasks; +} + std::shared_ptr MessageQueue::s_instance; MessageQueue::MessageQueue() @@ -163,6 +160,7 @@ MessageQueue::MessageQueue() , m_listenersLength(0) , m_loopIsRunning(false) , m_threadIsRunning(false) + , m_sendMessagesAsTasks(false) { m_frontMessageBuffer = std::make_shared(); m_backMessageBuffer = std::make_shared(); @@ -191,25 +189,60 @@ void MessageQueue::processMessages() m_frontMessageBuffer->pop(); } - std::lock_guard lock(m_listenersMutex); - - // m_listenersLength is saved, so that new listeners registered whithin message handling don't get the - // current message and the length can be reduced when a listener gets unregistered. - m_listenersLength = m_listeners.size(); - - // The currentListenerIndex holds the index of the current listener being handled, so it can be changed when a - // listener gets removed while message handling. - for (m_currentListenerIndex = 0; m_currentListenerIndex < m_listenersLength; m_currentListenerIndex++) + if (m_sendMessagesAsTasks && message->sendAsTask()) { - MessageListenerBase* listener = m_listeners[m_currentListenerIndex]; - - if (listener->getType() == message->getType()) - { - // The listenersMutex gets unlocked so changes to listeners are possible while message handling. - m_listenersMutex.unlock(); - listener->handleMessageBase(message.get()); - m_listenersMutex.lock(); - } + sendMessageAsTask(message); + } + else + { + sendMessage(message); } } } + +void MessageQueue::sendMessage(std::shared_ptr message) +{ + std::lock_guard lock(m_listenersMutex); + + // m_listenersLength is saved, so that new listeners registered whithin message handling don't get the + // current message and the length can be reduced when a listener gets unregistered. + m_listenersLength = m_listeners.size(); + + // The currentListenerIndex holds the index of the current listener being handled, so it can be changed when a + // listener gets removed while message handling. + for (m_currentListenerIndex = 0; m_currentListenerIndex < m_listenersLength; m_currentListenerIndex++) + { + MessageListenerBase* listener = m_listeners[m_currentListenerIndex]; + + if (listener->getType() == message->getType()) + { + // The listenersMutex gets unlocked so changes to listeners are possible while message handling. + m_listenersMutex.unlock(); + listener->handleMessageBase(message.get()); + m_listenersMutex.lock(); + } + } +} + +void MessageQueue::sendMessageAsTask(std::shared_ptr message) const +{ + std::shared_ptr taskGroup = std::make_shared(); + + std::lock_guard lock(m_listenersMutex); + for (size_t i = 0; i < m_listeners.size(); i++) + { + MessageListenerBase* listener = m_listeners[i]; + + if (listener->getType() == message->getType()) + { + taskGroup->addTask(std::make_shared( + [listener, message]() + { + listener->handleMessageBase(message.get()); + } + )); + } + } + + Task::dispatch(taskGroup); +} diff --git a/src/lib/utility/messaging/MessageQueue.h b/src/lib/utility/messaging/MessageQueue.h index 12372602..7232d809 100644 --- a/src/lib/utility/messaging/MessageQueue.h +++ b/src/lib/utility/messaging/MessageQueue.h @@ -13,7 +13,7 @@ class MessageQueue public: static std::shared_ptr getInstance(); - void registerListener(MessageListenerBase* listener, bool toFront = false); + void registerListener(MessageListenerBase* listener); void unregisterListener(MessageListenerBase* listener); void pushMessage(std::shared_ptr message); @@ -25,6 +25,8 @@ public: bool loopIsRunning() const; bool hasMessagesQueued() const; + void setSendMessagesAsTasks(bool sendMessagesAsTasks); + private: typedef std::queue> MessageBufferType; @@ -35,6 +37,8 @@ private: void operator=(const MessageQueue&); void processMessages(); + void sendMessage(std::shared_ptr message); + void sendMessageAsTask(std::shared_ptr message) const; std::shared_ptr m_frontMessageBuffer; std::shared_ptr m_backMessageBuffer; @@ -42,6 +46,7 @@ private: size_t m_currentListenerIndex; size_t m_listenersLength; + bool m_loopIsRunning; bool m_threadIsRunning; @@ -50,6 +55,8 @@ private: mutable std::mutex m_listenersMutex; mutable std::mutex m_loopMutex; mutable std::mutex m_threadMutex; + + bool m_sendMessagesAsTasks; }; #endif // MESSAGE_QUEUE_H diff --git a/src/lib/utility/messaging/type/MessageError.h b/src/lib/utility/messaging/type/MessageError.h deleted file mode 100644 index e61ee1be..00000000 --- a/src/lib/utility/messaging/type/MessageError.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef MESSAGE_ERROR_H -#define MESSAGE_ERROR_H - -#include "utility/messaging/Message.h" -#include "utility/types.h" - -class MessageError: public Message -{ -public: - MessageError( - const std::string& error - ) - : error(error) - - { - } - - static const std::string getStaticType() - { - return "MessageError"; - } - - const std::string error; -}; - -#endif // MESSAGE_ERROR_H diff --git a/src/lib/utility/messaging/type/MessageFinishedParsing.h b/src/lib/utility/messaging/type/MessageFinishedParsing.h index 1050868c..56abe641 100644 --- a/src/lib/utility/messaging/type/MessageFinishedParsing.h +++ b/src/lib/utility/messaging/type/MessageFinishedParsing.h @@ -1,7 +1,11 @@ #ifndef MESSAGE_FINISHED_PARSING_H #define MESSAGE_FINISHED_PARSING_H +#include +#include + #include "utility/messaging/Message.h" +#include "utility/messaging/type/MessageStatus.h" class MessageFinishedParsing: public Message { @@ -19,6 +23,23 @@ public: return "MessageFinishedParsing"; } + virtual void dispatch() + { + MessageStatus(getStatusStr(), errorCount > 0).dispatch(); + + Message::dispatch(); + } + + std::string getStatusStr() const + { + std::stringstream ss; + ss << "Parsing Finished: "; + ss << fileCount << "/" << totalFileCount << " files, "; + ss << std::setprecision(2) << std::fixed << parseTime << " seconds, "; + ss << errorCount << " error(s)"; + return ss.str(); + } + size_t fileCount; size_t totalFileCount; float parseTime; diff --git a/src/lib/utility/messaging/type/MessageInterruptTasks.h b/src/lib/utility/messaging/type/MessageInterruptTasks.h index 40c72414..fdd4fadf 100644 --- a/src/lib/utility/messaging/type/MessageInterruptTasks.h +++ b/src/lib/utility/messaging/type/MessageInterruptTasks.h @@ -9,6 +9,7 @@ class MessageInterruptTasks: public: MessageInterruptTasks() { + setSendAsTask(false); } static const std::string getStaticType() diff --git a/src/lib/utility/messaging/type/MessageStatus.h b/src/lib/utility/messaging/type/MessageStatus.h index 08a5c9eb..189f4b3d 100644 --- a/src/lib/utility/messaging/type/MessageStatus.h +++ b/src/lib/utility/messaging/type/MessageStatus.h @@ -2,17 +2,16 @@ #define MESSAGE_STATUS_H #include "utility/messaging/Message.h" -#include "utility/types.h" -class MessageStatus: public Message +class MessageStatus + : public Message { public: - MessageStatus( - const std::string& status - ) + MessageStatus(const std::string& status, bool isError = false) : status(status) - + , isError(isError) { + setSendAsTask(false); } static const std::string getStaticType() @@ -21,6 +20,7 @@ public: } const std::string status; + const bool isError; }; #endif // MESSAGE_STATUS_H diff --git a/src/lib/utility/scheduling/LambdaTask.cpp b/src/lib/utility/scheduling/LambdaTask.cpp new file mode 100644 index 00000000..f17ef74e --- /dev/null +++ b/src/lib/utility/scheduling/LambdaTask.cpp @@ -0,0 +1,15 @@ +#include "utility/scheduling/LambdaTask.h" + +LambdaTask::LambdaTask(std::function func) + : m_func(func) +{ +} + +LambdaTask::~LambdaTask() +{ +} + +void LambdaTask::perform() +{ + m_func(); +} diff --git a/src/lib/utility/scheduling/LambdaTask.h b/src/lib/utility/scheduling/LambdaTask.h new file mode 100644 index 00000000..7c2f5609 --- /dev/null +++ b/src/lib/utility/scheduling/LambdaTask.h @@ -0,0 +1,21 @@ +#ifndef LAMBDA_TASK_H +#define LAMBDA_TASK_H + +#include + +#include "utility/scheduling/SimpleTask.h" + +class LambdaTask + : public SimpleTask +{ +public: + LambdaTask(std::function func); + virtual ~LambdaTask(); + + virtual void perform(); + +private: + std::function m_func; +}; + +#endif // LAMBDA_TASK_H diff --git a/src/lib/utility/scheduling/SimpleTask.cpp b/src/lib/utility/scheduling/SimpleTask.cpp new file mode 100644 index 00000000..cc6f0af1 --- /dev/null +++ b/src/lib/utility/scheduling/SimpleTask.cpp @@ -0,0 +1,28 @@ +#include "utility/scheduling/SimpleTask.h" + +void SimpleTask::enter() +{ + +} + +Task::TaskState SimpleTask::update() +{ + perform(); + + return Task::STATE_FINISHED; +} + +void SimpleTask::exit() +{ + +} + +void SimpleTask::interrupt() +{ + +} + +void SimpleTask::revert() +{ + +} diff --git a/src/lib/utility/scheduling/SimpleTask.h b/src/lib/utility/scheduling/SimpleTask.h new file mode 100644 index 00000000..f9408f64 --- /dev/null +++ b/src/lib/utility/scheduling/SimpleTask.h @@ -0,0 +1,20 @@ +#ifndef SIMPLE_TASK_H +#define SIMPLE_TASK_H + +#include "utility/scheduling/Task.h" + +class SimpleTask + : public Task +{ +public: + virtual void enter(); + virtual TaskState update(); + virtual void exit(); + + virtual void interrupt(); + virtual void revert(); + + virtual void perform() = 0; +}; + +#endif // SIMPLE_TASK_H diff --git a/src/test/MessageQueueTestSuite.h b/src/test/MessageQueueTestSuite.h index a5d22d91..d9404b9a 100644 --- a/src/test/MessageQueueTestSuite.h +++ b/src/test/MessageQueueTestSuite.h @@ -152,9 +152,8 @@ private: class TestMessageListener: public MessageListener { public: - TestMessageListener(bool toFront = false) - : MessageListener(toFront) - , m_messageCount(0) + TestMessageListener() + : m_messageCount(0) { } @@ -232,7 +231,7 @@ private: { for (size_t i = 0; i < 5; i++) { - m_listeners.push_back(std::make_shared(i % 2 == 1)); + m_listeners.push_back(std::make_shared()); } } }