From fb72f73567e1e50d70e67d994fe835741506381c Mon Sep 17 00:00:00 2001 From: malte_langkabel Date: Fri, 11 Nov 2016 15:40:28 +0100 Subject: [PATCH] ui: split steps of indexing files and saving the last few batches of data * implemented showing dialog for database injection * implemented easy-to-read way of creating behavior tree structures * moved injector wait logic out of injection task --- src/lib/CMakeLists.txt | 14 +++- src/lib/Project.cpp | 54 ++++++++++--- src/lib/data/TaskInjectStorage.cpp | 24 ------ src/lib/data/TaskShowDialogView.cpp | 36 +++++++++ src/lib/data/TaskShowDialogView.h | 33 ++++++++ src/lib/utility/messaging/MessageQueue.cpp | 4 +- src/lib/utility/scheduling/TaskDecorator.cpp | 6 ++ src/lib/utility/scheduling/TaskDecorator.h | 2 + .../scheduling/TaskDecoratorRepeat.cpp | 50 ++++++++++++ ...atWhileSuccess.h => TaskDecoratorRepeat.h} | 16 ++-- src/lib/utility/scheduling/TaskGroup.cpp | 21 +++++ src/lib/utility/scheduling/TaskGroup.h | 6 ++ .../utility/scheduling/TaskGroupSelector.cpp | 56 +++++++++++++ ...kGroupSequential.h => TaskGroupSelector.h} | 12 +-- ...upSequential.cpp => TaskGroupSequence.cpp} | 17 ++-- .../utility/scheduling/TaskGroupSequence.h | 26 +++++++ .../scheduling/TaskRepeatWhileSuccess.cpp | 44 ----------- .../scheduling/TaskReturnSuccessWhile.cpp | 0 .../scheduling/TaskReturnSuccessWhile.h | 78 +++++++++++++++++++ src/test/TaskSchedulerTestSuite.h | 40 +++++++++- 20 files changed, 431 insertions(+), 108 deletions(-) create mode 100644 src/lib/data/TaskShowDialogView.cpp create mode 100644 src/lib/data/TaskShowDialogView.h create mode 100644 src/lib/utility/scheduling/TaskDecoratorRepeat.cpp rename src/lib/utility/scheduling/{TaskRepeatWhileSuccess.h => TaskDecoratorRepeat.h} (65%) create mode 100644 src/lib/utility/scheduling/TaskGroupSelector.cpp rename src/lib/utility/scheduling/{TaskGroupSequential.h => TaskGroupSelector.h} (74%) rename src/lib/utility/scheduling/{TaskGroupSequential.cpp => TaskGroupSequence.cpp} (50%) create mode 100644 src/lib/utility/scheduling/TaskGroupSequence.h delete mode 100644 src/lib/utility/scheduling/TaskRepeatWhileSuccess.cpp create mode 100644 src/lib/utility/scheduling/TaskReturnSuccessWhile.cpp create mode 100644 src/lib/utility/scheduling/TaskReturnSuccessWhile.h diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 8449b85a..0b119cef 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -201,6 +201,8 @@ add_files( data/TaskFinishParsing.h data/TaskInjectStorage.cpp data/TaskInjectStorage.h + data/TaskShowDialogView.cpp + data/TaskShowDialogView.h settings/ApplicationSettings.cpp settings/ApplicationSettings.h @@ -325,16 +327,20 @@ add_files( utility/scheduling/Task.h utility/scheduling/TaskDecorator.cpp utility/scheduling/TaskDecorator.h + utility/scheduling/TaskDecoratorRepeat.cpp + utility/scheduling/TaskDecoratorRepeat.h utility/scheduling/TaskGroup.cpp utility/scheduling/TaskGroup.h utility/scheduling/TaskGroupParallel.cpp utility/scheduling/TaskGroupParallel.h - utility/scheduling/TaskGroupSequential.cpp - utility/scheduling/TaskGroupSequential.h + utility/scheduling/TaskGroupSelector.cpp + utility/scheduling/TaskGroupSelector.h + utility/scheduling/TaskGroupSequence.cpp + utility/scheduling/TaskGroupSequence.h utility/scheduling/TaskLambda.cpp utility/scheduling/TaskLambda.h - utility/scheduling/TaskRepeatWhileSuccess.cpp - utility/scheduling/TaskRepeatWhileSuccess.h + utility/scheduling/TaskReturnSuccessWhile.cpp + utility/scheduling/TaskReturnSuccessWhile.h utility/scheduling/TaskRunner.cpp utility/scheduling/TaskRunner.h utility/scheduling/TaskScheduler.cpp diff --git a/src/lib/Project.cpp b/src/lib/Project.cpp index fcf66819..aadda426 100644 --- a/src/lib/Project.cpp +++ b/src/lib/Project.cpp @@ -7,6 +7,7 @@ #include "data/StorageProvider.h" #include "data/PersistentStorage.h" #include "data/TaskCleanStorage.h" +#include "data/TaskShowDialogView.h" #include "data/TaskFinishParsing.h" #include "data/TaskInjectStorage.h" #include "settings/ApplicationSettings.h" @@ -17,9 +18,11 @@ #include "utility/messaging/type/MessageFinishedParsing.h" #include "utility/messaging/type/MessageRefresh.h" #include "utility/messaging/type/MessageStatus.h" -#include "utility/scheduling/TaskGroupSequential.h" +#include "utility/scheduling/TaskDecoratorRepeat.h" +#include "utility/scheduling/TaskGroupSelector.h" +#include "utility/scheduling/TaskGroupSequence.h" #include "utility/scheduling/TaskGroupParallel.h" -#include "utility/scheduling/TaskRepeatWhileSuccess.h" +#include "utility/scheduling/TaskReturnSuccessWhile.h" #include "utility/text/TextAccess.h" #include "utility/utility.h" #include "utility/utilityString.h" @@ -305,9 +308,9 @@ bool Project::buildIndex(bool forceRefresh) m_storage->setProjectSettingsText(TextAccess::createFromFile(getProjectSettingsFilePath().str())->getText()); - std::shared_ptr taskSequential = std::make_shared(); + std::shared_ptr taskSequential = std::make_shared(); - if (filesToClean.size()) + if (!filesToClean.empty()) { taskSequential->addTask(std::make_shared( m_storage.get(), @@ -320,7 +323,7 @@ bool Project::buildIndex(bool forceRefresh) std::shared_ptr fileRegister = std::make_shared(&m_fileManager, indexerThreadCount > 1); - if (filesToParse.size()) + if (!filesToParse.empty()) { fileRegister->setFilePaths(utility::toVector(filesToParse)); @@ -338,16 +341,45 @@ bool Project::buildIndex(bool forceRefresh) for (size_t i = 0; i < indexerThreadCount && i < filesToParse.size(); i++) { - std::shared_ptr taskRepeat = std::make_shared(Task::STATE_SUCCESS); - taskParallelIndexing->addTask(taskRepeat); - taskRepeat->setTask(createIndexerTask(storageProvider, fileRegister)); + taskParallelIndexing->addChildTasks( + std::make_shared(TaskDecoratorRepeat::CONDITION_WHILE_SUCCESS, Task::STATE_SUCCESS)->addChildTask( + createIndexerTask(storageProvider, fileRegister) + ) + ); } - std::shared_ptr taskRepeat = std::make_shared(Task::STATE_SUCCESS); - taskParallelIndexing->addTask(taskRepeat); - taskRepeat->setTask(std::make_shared(storageProvider, m_storage)); + taskParallelIndexing->addTask( + std::make_shared()->addChildTasks( + std::make_shared(TaskDecoratorRepeat::CONDITION_WHILE_SUCCESS, Task::STATE_SUCCESS)->addChildTask( + std::make_shared>("indexer_count", TaskReturnSuccessWhile::CONDITION_EQUALS, 0) + ), + std::make_shared(TaskDecoratorRepeat::CONDITION_WHILE_SUCCESS, Task::STATE_SUCCESS)->addChildTask( + std::make_shared()->addChildTasks( + // stopping when indexer count is zero, regardless wether there are still storages left to insert. + std::make_shared>("indexer_count", TaskReturnSuccessWhile::CONDITION_GREATER_THAN, 0), + std::make_shared()->addChildTasks( + std::make_shared(storageProvider, m_storage), + // continuing when indexer count is greater than zero, even if there are no storages right now. + std::make_shared>("indexer_count", TaskReturnSuccessWhile::CONDITION_GREATER_THAN, 0) + ) + ) + ) + ) + ); + + taskSequential->addTask( // we don't need to hide this dialog again, because it's overridden by other dialogs later on. + std::make_shared("Finish Indexing", "Saving\nRemaining Data", m_dialogView) + ); + + taskSequential->addTask( + std::make_shared(TaskDecoratorRepeat::CONDITION_WHILE_SUCCESS, Task::STATE_SUCCESS)->addChildTask( + std::make_shared(storageProvider, m_storage) + ) + ); } + + taskSequential->addTask(std::make_shared(m_storage.get(), m_storageAccessProxy, fileRegister, m_dialogView)); Task::dispatch(taskSequential); diff --git a/src/lib/data/TaskInjectStorage.cpp b/src/lib/data/TaskInjectStorage.cpp index f538bb0a..4f6f8961 100644 --- a/src/lib/data/TaskInjectStorage.cpp +++ b/src/lib/data/TaskInjectStorage.cpp @@ -19,20 +19,6 @@ TaskInjectStorage::TaskInjectStorage( void TaskInjectStorage::doEnter(std::shared_ptr blackboard) { - while (!m_hasInjected) - { - int indexerCount = 0; - if (blackboard->get("indexer_count", indexerCount)) - { - if (indexerCount > 0 || m_storageProvider->getStorageCount() > 0) - { - break; - } - } - - const int SLEEP_TIME_MS = 25; - std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_MS)); - } } Task::TaskState TaskInjectStorage::doUpdate(std::shared_ptr blackboard) @@ -43,7 +29,6 @@ Task::TaskState TaskInjectStorage::doUpdate(std::shared_ptr blackboa if (source) { m_target->inject(source.get()); - m_hasInjected = true; return STATE_SUCCESS; } } @@ -53,15 +38,6 @@ Task::TaskState TaskInjectStorage::doUpdate(std::shared_ptr blackboa std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_MS)); } - int indexerCount = 0; - if (blackboard->get("indexer_count", indexerCount)) - { - if (indexerCount > 0 || m_storageProvider->getStorageCount() > 0) - { - return STATE_SUCCESS; - } - } - return STATE_FAILURE; } diff --git a/src/lib/data/TaskShowDialogView.cpp b/src/lib/data/TaskShowDialogView.cpp new file mode 100644 index 00000000..caf9f215 --- /dev/null +++ b/src/lib/data/TaskShowDialogView.cpp @@ -0,0 +1,36 @@ +#include "data/TaskShowDialogView.h" + +#include "component/view/DialogView.h" + +TaskShowDialogView::TaskShowDialogView( + const std::string& title, + const std::string& message, + DialogView* dialogView +) + : m_title(title) + , m_message(message) + , m_dialogView(dialogView) +{ +} + +TaskShowDialogView::~TaskShowDialogView() +{ +} + +void TaskShowDialogView::doEnter(std::shared_ptr blackboard) +{ +} + +Task::TaskState TaskShowDialogView::doUpdate(std::shared_ptr blackboard) +{ + m_dialogView->showProgressDialog(m_title, m_message); + return STATE_SUCCESS; +} + +void TaskShowDialogView::doExit(std::shared_ptr blackboard) +{ +} + +void TaskShowDialogView::doReset(std::shared_ptr blackboard) +{ +} diff --git a/src/lib/data/TaskShowDialogView.h b/src/lib/data/TaskShowDialogView.h new file mode 100644 index 00000000..64ab04a9 --- /dev/null +++ b/src/lib/data/TaskShowDialogView.h @@ -0,0 +1,33 @@ +#ifndef TASK_SHOW_DIALOG_VIEW_H +#define TASK_SHOW_DIALOG_VIEW_H + +#include + +#include "utility/scheduling/Task.h" + +class DialogView; + +class TaskShowDialogView + : public Task +{ +public: + TaskShowDialogView( + const std::string& title, + const std::string& message, + DialogView* dialogView + ); + + virtual ~TaskShowDialogView(); + +private: + virtual void doEnter(std::shared_ptr blackboard); + virtual TaskState doUpdate(std::shared_ptr blackboard); + virtual void doExit(std::shared_ptr blackboard); + virtual void doReset(std::shared_ptr blackboard); + + const std::string m_title; + const std::string m_message; + DialogView* m_dialogView; +}; + +#endif // TASK_SHOW_DIALOG_VIEW_H diff --git a/src/lib/utility/messaging/MessageQueue.cpp b/src/lib/utility/messaging/MessageQueue.cpp index fe269edf..f628e256 100644 --- a/src/lib/utility/messaging/MessageQueue.cpp +++ b/src/lib/utility/messaging/MessageQueue.cpp @@ -6,7 +6,7 @@ #include "utility/logging/logging.h" #include "utility/messaging/MessageBase.h" #include "utility/messaging/MessageListenerBase.h" -#include "utility/scheduling/TaskGroupSequential.h" +#include "utility/scheduling/TaskGroupSequence.h" #include "utility/scheduling/TaskLambda.h" std::shared_ptr MessageQueue::getInstance() @@ -258,7 +258,7 @@ void MessageQueue::sendMessage(std::shared_ptr message) void MessageQueue::sendMessageAsTask(std::shared_ptr message, bool asNextTask) const { - std::shared_ptr taskGroup = std::make_shared(); + std::shared_ptr taskGroup = std::make_shared(); { std::lock_guard lock(m_listenersMutex); diff --git a/src/lib/utility/scheduling/TaskDecorator.cpp b/src/lib/utility/scheduling/TaskDecorator.cpp index a106ec6c..56e24bb5 100644 --- a/src/lib/utility/scheduling/TaskDecorator.cpp +++ b/src/lib/utility/scheduling/TaskDecorator.cpp @@ -7,3 +7,9 @@ TaskDecorator::TaskDecorator() TaskDecorator::~TaskDecorator() { } + +std::shared_ptr TaskDecorator::addChildTask(std::shared_ptr child) +{ + setTask(child); + return shared_from_this(); +} diff --git a/src/lib/utility/scheduling/TaskDecorator.h b/src/lib/utility/scheduling/TaskDecorator.h index e50a95ee..cabb3929 100644 --- a/src/lib/utility/scheduling/TaskDecorator.h +++ b/src/lib/utility/scheduling/TaskDecorator.h @@ -7,10 +7,12 @@ class TaskDecorator : public Task + , public std::enable_shared_from_this { public: TaskDecorator(); virtual ~TaskDecorator(); + std::shared_ptr addChildTask(std::shared_ptr child); virtual void setTask(std::shared_ptr task) = 0; }; diff --git a/src/lib/utility/scheduling/TaskDecoratorRepeat.cpp b/src/lib/utility/scheduling/TaskDecoratorRepeat.cpp new file mode 100644 index 00000000..88404791 --- /dev/null +++ b/src/lib/utility/scheduling/TaskDecoratorRepeat.cpp @@ -0,0 +1,50 @@ +#include "utility/scheduling/TaskDecoratorRepeat.h" + +TaskDecoratorRepeat::TaskDecoratorRepeat(ConditionType condition, TaskState exitState) + : m_condition(condition) + , m_exitState(exitState) +{ +} + +void TaskDecoratorRepeat::setTask(std::shared_ptr task) +{ + if (task) + { + m_taskRunner = std::make_shared(task); + } +} + +void TaskDecoratorRepeat::doEnter(std::shared_ptr blackboard) +{ +} + +Task::TaskState TaskDecoratorRepeat::doUpdate(std::shared_ptr blackboard) +{ + TaskState state = m_taskRunner->update(blackboard); + + switch (m_condition) + { + case CONDITION_WHILE_SUCCESS: + if (state == Task::STATE_SUCCESS) + { + m_taskRunner->reset(); + state = Task::STATE_RUNNING; + } + else if (state == Task::STATE_FAILURE) + { + state = m_exitState; + } + break; + } + + return state; +} + +void TaskDecoratorRepeat::doExit(std::shared_ptr blackboard) +{ +} + +void TaskDecoratorRepeat::doReset(std::shared_ptr blackboard) +{ + m_taskRunner->reset(); +} diff --git a/src/lib/utility/scheduling/TaskRepeatWhileSuccess.h b/src/lib/utility/scheduling/TaskDecoratorRepeat.h similarity index 65% rename from src/lib/utility/scheduling/TaskRepeatWhileSuccess.h rename to src/lib/utility/scheduling/TaskDecoratorRepeat.h index fc66e7f3..ceeb9374 100644 --- a/src/lib/utility/scheduling/TaskRepeatWhileSuccess.h +++ b/src/lib/utility/scheduling/TaskDecoratorRepeat.h @@ -1,16 +1,21 @@ -#ifndef TASK_REPEAT_WHILE_SUCCESS_H -#define TASK_REPEAT_WHILE_SUCCESS_H +#ifndef TASK_DECORATOR_REPEAT_H +#define TASK_DECORATOR_REPEAT_H #include #include "utility/scheduling/TaskDecorator.h" #include "utility/scheduling/TaskRunner.h" -class TaskRepeatWhileSuccess +class TaskDecoratorRepeat : public TaskDecorator { public: - TaskRepeatWhileSuccess(TaskState exitState); + enum ConditionType + { + CONDITION_WHILE_SUCCESS + }; + + TaskDecoratorRepeat(ConditionType condition, TaskState exitState); virtual void setTask(std::shared_ptr task); @@ -21,7 +26,8 @@ private: virtual void doReset(std::shared_ptr blackboard); std::shared_ptr m_taskRunner; + const ConditionType m_condition; const TaskState m_exitState; }; -#endif // TASK_REPEAT_WHILE_SUCCESS_H +#endif // TASK_DECORATOR_REPEAT_H diff --git a/src/lib/utility/scheduling/TaskGroup.cpp b/src/lib/utility/scheduling/TaskGroup.cpp index 7a70c5a6..77e2c9bc 100644 --- a/src/lib/utility/scheduling/TaskGroup.cpp +++ b/src/lib/utility/scheduling/TaskGroup.cpp @@ -7,3 +7,24 @@ TaskGroup::TaskGroup() TaskGroup::~TaskGroup() { } + +std::shared_ptr TaskGroup::addChildTasks(std::shared_ptr child1) +{ + addTask(child1); + return shared_from_this(); +} + +std::shared_ptr TaskGroup::addChildTasks(std::shared_ptr child1, std::shared_ptr child2) +{ + addTask(child1); + addTask(child2); + return shared_from_this(); +} + +std::shared_ptr TaskGroup::addChildTasks(std::shared_ptr child1, std::shared_ptr child2, std::shared_ptr child3) +{ + addTask(child1); + addTask(child2); + addTask(child3); + return shared_from_this(); +} \ No newline at end of file diff --git a/src/lib/utility/scheduling/TaskGroup.h b/src/lib/utility/scheduling/TaskGroup.h index 9dd4c712..70ee3fa3 100644 --- a/src/lib/utility/scheduling/TaskGroup.h +++ b/src/lib/utility/scheduling/TaskGroup.h @@ -8,12 +8,18 @@ class TaskGroup : public Task + , public std::enable_shared_from_this { public: TaskGroup(); virtual ~TaskGroup(); + std::shared_ptr addChildTasks(std::shared_ptr child1); + std::shared_ptr addChildTasks(std::shared_ptr child1, std::shared_ptr child2); + std::shared_ptr addChildTasks(std::shared_ptr child1, std::shared_ptr child2, std::shared_ptr child3); virtual void addTask(std::shared_ptr task) = 0; }; + + #endif // TASK_GROUP_H diff --git a/src/lib/utility/scheduling/TaskGroupSelector.cpp b/src/lib/utility/scheduling/TaskGroupSelector.cpp new file mode 100644 index 00000000..ecdc5cca --- /dev/null +++ b/src/lib/utility/scheduling/TaskGroupSelector.cpp @@ -0,0 +1,56 @@ +#include "utility/scheduling/TaskGroupSelector.h" + +TaskGroupSelector::TaskGroupSelector() +{ +} + +TaskGroupSelector::~TaskGroupSelector() +{ +} + +void TaskGroupSelector::addTask(std::shared_ptr task) +{ + m_taskRunners.push_back(std::make_shared(task)); +} + +void TaskGroupSelector::doEnter(std::shared_ptr blackboard) +{ + m_taskIndex = 0; +} + +Task::TaskState TaskGroupSelector::doUpdate(std::shared_ptr blackboard) +{ + if (m_taskIndex >= int(m_taskRunners.size())) + { + return STATE_FAILURE; + } + else if (m_taskIndex < 0) + { + return STATE_SUCCESS; + } + + TaskState state = m_taskRunners[m_taskIndex]->update(blackboard); + + if (state == STATE_FAILURE) + { + m_taskIndex++; + } + else if (state == STATE_SUCCESS) + { + m_taskIndex = -1; + } + + return STATE_RUNNING; +} + +void TaskGroupSelector::doExit(std::shared_ptr blackboard) +{ +} + +void TaskGroupSelector::doReset(std::shared_ptr blackboard) +{ + for (size_t i = 0; i < m_taskRunners.size(); i++) + { + m_taskRunners[i]->reset(); + } +} diff --git a/src/lib/utility/scheduling/TaskGroupSequential.h b/src/lib/utility/scheduling/TaskGroupSelector.h similarity index 74% rename from src/lib/utility/scheduling/TaskGroupSequential.h rename to src/lib/utility/scheduling/TaskGroupSelector.h index 3ee1c450..65f8a943 100644 --- a/src/lib/utility/scheduling/TaskGroupSequential.h +++ b/src/lib/utility/scheduling/TaskGroupSelector.h @@ -1,15 +1,15 @@ -#ifndef TASK_GROUP_SEQUENTIAL_H -#define TASK_GROUP_SEQUENTIAL_H +#ifndef TASK_GROUP_SELECTOR_H +#define TASK_GROUP_SELECTOR_H #include "utility/scheduling/TaskGroup.h" #include "utility/scheduling/TaskRunner.h" -class TaskGroupSequential +class TaskGroupSelector : public TaskGroup { public: - TaskGroupSequential(); - virtual ~TaskGroupSequential(); + TaskGroupSelector(); + virtual ~TaskGroupSelector(); virtual void addTask(std::shared_ptr task); @@ -23,4 +23,4 @@ private: int m_taskIndex; }; -#endif // TASK_GROUP_SEQUENTIAL_H +#endif // TASK_GROUP_SELECTOR_H diff --git a/src/lib/utility/scheduling/TaskGroupSequential.cpp b/src/lib/utility/scheduling/TaskGroupSequence.cpp similarity index 50% rename from src/lib/utility/scheduling/TaskGroupSequential.cpp rename to src/lib/utility/scheduling/TaskGroupSequence.cpp index 203cf5c7..caf3cbaf 100644 --- a/src/lib/utility/scheduling/TaskGroupSequential.cpp +++ b/src/lib/utility/scheduling/TaskGroupSequence.cpp @@ -1,25 +1,24 @@ -#include "utility/scheduling/TaskGroupSequential.h" -#include +#include "utility/scheduling/TaskGroupSequence.h" -TaskGroupSequential::TaskGroupSequential() +TaskGroupSequence::TaskGroupSequence() { } -TaskGroupSequential::~TaskGroupSequential() +TaskGroupSequence::~TaskGroupSequence() { } -void TaskGroupSequential::addTask(std::shared_ptr task) +void TaskGroupSequence::addTask(std::shared_ptr task) { m_taskRunners.push_back(std::make_shared(task)); } -void TaskGroupSequential::doEnter(std::shared_ptr blackboard) +void TaskGroupSequence::doEnter(std::shared_ptr blackboard) { m_taskIndex = 0; } -Task::TaskState TaskGroupSequential::doUpdate(std::shared_ptr blackboard) +Task::TaskState TaskGroupSequence::doUpdate(std::shared_ptr blackboard) { if (m_taskIndex >= int(m_taskRunners.size())) { @@ -44,11 +43,11 @@ Task::TaskState TaskGroupSequential::doUpdate(std::shared_ptr blackb return STATE_RUNNING; } -void TaskGroupSequential::doExit(std::shared_ptr blackboard) +void TaskGroupSequence::doExit(std::shared_ptr blackboard) { } -void TaskGroupSequential::doReset(std::shared_ptr blackboard) +void TaskGroupSequence::doReset(std::shared_ptr blackboard) { for (size_t i = 0; i < m_taskRunners.size(); i++) { diff --git a/src/lib/utility/scheduling/TaskGroupSequence.h b/src/lib/utility/scheduling/TaskGroupSequence.h new file mode 100644 index 00000000..4085014a --- /dev/null +++ b/src/lib/utility/scheduling/TaskGroupSequence.h @@ -0,0 +1,26 @@ +#ifndef TASK_GROUP_SEQUENCE_H +#define TASK_GROUP_SEQUENCE_H + +#include "utility/scheduling/TaskGroup.h" +#include "utility/scheduling/TaskRunner.h" + +class TaskGroupSequence + : public TaskGroup +{ +public: + TaskGroupSequence(); + virtual ~TaskGroupSequence(); + + virtual void addTask(std::shared_ptr task); + +private: + virtual void doEnter(std::shared_ptr blackboard); + virtual TaskState doUpdate(std::shared_ptr blackboard); + virtual void doExit(std::shared_ptr blackboard); + virtual void doReset(std::shared_ptr blackboard); + + std::vector> m_taskRunners; + int m_taskIndex; +}; + +#endif // TASK_GROUP_SEQUENCE_H diff --git a/src/lib/utility/scheduling/TaskRepeatWhileSuccess.cpp b/src/lib/utility/scheduling/TaskRepeatWhileSuccess.cpp deleted file mode 100644 index fa468efe..00000000 --- a/src/lib/utility/scheduling/TaskRepeatWhileSuccess.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "utility/scheduling/TaskRepeatWhileSuccess.h" - -TaskRepeatWhileSuccess::TaskRepeatWhileSuccess(TaskState exitState) - : m_exitState(exitState) -{ -} - -void TaskRepeatWhileSuccess::setTask(std::shared_ptr task) -{ - if (task) - { - m_taskRunner = std::make_shared(task); - } -} - -void TaskRepeatWhileSuccess::doEnter(std::shared_ptr blackboard) -{ -} - -Task::TaskState TaskRepeatWhileSuccess::doUpdate(std::shared_ptr blackboard) -{ - TaskState state = m_taskRunner->update(blackboard); - - if (state == Task::STATE_SUCCESS) - { - m_taskRunner->reset(); - state = Task::STATE_RUNNING; - } - else if (state == Task::STATE_FAILURE) - { - state = m_exitState; - } - - return state; -} - -void TaskRepeatWhileSuccess::doExit(std::shared_ptr blackboard) -{ -} - -void TaskRepeatWhileSuccess::doReset(std::shared_ptr blackboard) -{ - m_taskRunner->reset(); -} diff --git a/src/lib/utility/scheduling/TaskReturnSuccessWhile.cpp b/src/lib/utility/scheduling/TaskReturnSuccessWhile.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/lib/utility/scheduling/TaskReturnSuccessWhile.h b/src/lib/utility/scheduling/TaskReturnSuccessWhile.h new file mode 100644 index 00000000..4192165f --- /dev/null +++ b/src/lib/utility/scheduling/TaskReturnSuccessWhile.h @@ -0,0 +1,78 @@ +#ifndef TASK_RETURN_SUCCESS_WHILE_H +#define TASK_RETURN_SUCCESS_WHILE_H + +#include + +#include "utility/scheduling/Task.h" +#include "utility/scheduling/Blackboard.h" + +template +class TaskReturnSuccessWhile: + public Task +{ +public: + enum ConditionType + { + CONDITION_GREATER_THAN, + CONDITION_EQUALS + }; + + TaskReturnSuccessWhile(const std::string& lhsValueName, ConditionType condition, T rhsValue); + +private: + virtual void doEnter(std::shared_ptr blackboard); + virtual TaskState doUpdate(std::shared_ptr blackboard); + virtual void doExit(std::shared_ptr blackboard); + virtual void doReset(std::shared_ptr blackboard); + + const std::string m_lhsValueName; + const ConditionType m_condition; + const T m_rhsValue; +}; + +template +TaskReturnSuccessWhile::TaskReturnSuccessWhile(const std::string& lhsValueName, ConditionType condition, T rhsValue) + : m_lhsValueName(lhsValueName) + , m_condition(condition) + , m_rhsValue(rhsValue) +{ +} + +template +void TaskReturnSuccessWhile::doEnter(std::shared_ptr blackboard) +{ +} + +template +Task::TaskState TaskReturnSuccessWhile::doUpdate(std::shared_ptr blackboard) +{ + const int SLEEP_TIME_MS = 25; + std::this_thread::sleep_for(std::chrono::microseconds(SLEEP_TIME_MS)); + + T lhsValue = 0; + blackboard->get(m_lhsValueName, lhsValue); + + switch (m_condition) + { + case CONDITION_GREATER_THAN: + if (lhsValue > m_rhsValue) + { + return STATE_SUCCESS; + } + break; + } + + return STATE_FAILURE; +} + +template +void TaskReturnSuccessWhile::doExit(std::shared_ptr blackboard) +{ +} + +template +void TaskReturnSuccessWhile::doReset(std::shared_ptr blackboard) +{ +} + +#endif // TASK_RETURN_SUCCESS_WHILE_H diff --git a/src/test/TaskSchedulerTestSuite.h b/src/test/TaskSchedulerTestSuite.h index cfd9c8a6..763ea750 100644 --- a/src/test/TaskSchedulerTestSuite.h +++ b/src/test/TaskSchedulerTestSuite.h @@ -5,7 +5,8 @@ #include "utility/scheduling/Blackboard.h" #include "utility/scheduling/Task.h" -#include "utility/scheduling/TaskGroupSequential.h" +#include "utility/scheduling/TaskGroupSelector.h" +#include "utility/scheduling/TaskGroupSequence.h" #include "utility/scheduling/TaskScheduler.h" class TaskSchedulerTestSuite: public CxxTest::TestSuite @@ -70,7 +71,7 @@ public: std::shared_ptr task1 = std::make_shared(&order, 1); std::shared_ptr task2 = std::make_shared(&order, 1); - std::shared_ptr taskGroup = std::make_shared(); + std::shared_ptr taskGroup = std::make_shared(); taskGroup->addTask(task1); taskGroup->addTask(task2); @@ -99,7 +100,7 @@ public: std::shared_ptr task1 = std::make_shared(&order, 1, Task::STATE_FAILURE); std::shared_ptr task2 = std::make_shared(&order, -1); - std::shared_ptr taskGroup = std::make_shared(); + std::shared_ptr taskGroup = std::make_shared(); taskGroup->addTask(task1); taskGroup->addTask(task2); @@ -118,6 +119,39 @@ public: TS_ASSERT_EQUALS(0, task2->exitCallOrder); } + void test_sequential_task_group_does_not_evaluate_tasks_after_success(void) + { + TaskScheduler::getInstance()->startSchedulerLoopThreaded(); + + int order = 0; + std::shared_ptr task1 = std::make_shared(&order, 1, Task::STATE_FAILURE); + std::shared_ptr task2 = std::make_shared(&order, 1, Task::STATE_SUCCESS); + std::shared_ptr task3 = std::make_shared(&order, -1); + + std::shared_ptr taskGroup = std::make_shared(); + taskGroup->addTask(task1); + taskGroup->addTask(task2); + taskGroup->addTask(task3); + + Task::dispatch(taskGroup); + + waitForThread(); + + TaskScheduler::getInstance()->stopSchedulerLoop(); + + TS_ASSERT_EQUALS(1, task1->enterCallOrder); + TS_ASSERT_EQUALS(2, task1->updateCallOrder); + TS_ASSERT_EQUALS(3, task1->exitCallOrder); + + TS_ASSERT_EQUALS(4, task2->enterCallOrder); + TS_ASSERT_EQUALS(5, task2->updateCallOrder); + TS_ASSERT_EQUALS(6, task2->exitCallOrder); + + TS_ASSERT_EQUALS(0, task3->enterCallOrder); + TS_ASSERT_EQUALS(0, task3->updateCallOrder); + TS_ASSERT_EQUALS(0, task3->exitCallOrder); + } + void test_task_scheduling_within_task_processing() { TaskScheduler::getInstance()->startSchedulerLoopThreaded();