]> git.tdb.fi Git - builder.git/commitdiff
Add utility class for executing chains of tasks
authorMikko Rasa <tdb@tdb.fi>
Thu, 9 Oct 2014 17:46:37 +0000 (20:46 +0300)
committerMikko Rasa <tdb@tdb.fi>
Thu, 9 Oct 2014 17:46:37 +0000 (20:46 +0300)
source/chainedtask.cpp [new file with mode: 0644]
source/chainedtask.h [new file with mode: 0644]

diff --git a/source/chainedtask.cpp b/source/chainedtask.cpp
new file mode 100644 (file)
index 0000000..066dc22
--- /dev/null
@@ -0,0 +1,75 @@
+#include "chainedtask.h"
+
+using namespace std;
+
+ChainedTask::ChainedTask(Task *t):
+       current(0),
+       final_status(RUNNING)
+{
+       add_task(t);
+}
+
+ChainedTask::~ChainedTask()
+{
+       for(vector<Task *>::iterator i=tasks.begin(); i!=tasks.end(); ++i)
+               delete *i;
+}
+
+void ChainedTask::add_task(Task *t)
+{
+       tasks.push_back(t);
+}
+
+string ChainedTask::get_command() const
+{
+       string cmd;
+       for(vector<Task *>::const_iterator i=tasks.begin(); i!=tasks.end(); ++i)
+       {
+               if(i!=tasks.begin())
+                       cmd += '\n';
+               cmd += (*i)->get_command();
+       }
+       return cmd;
+}
+
+void ChainedTask::start()
+{
+       prepare();
+
+       current = 0;
+       tasks[current]->start();
+}
+
+Task::Status ChainedTask::check()
+{
+       while(current<tasks.size() && !process(tasks[current]->check())) ;
+
+       return final_status;
+}
+
+Task::Status ChainedTask::wait()
+{
+       while(current<tasks.size() && !process(tasks[current]->wait())) ;
+
+       return final_status;
+}
+
+bool ChainedTask::process(Status sub_status)
+{
+       if(sub_status==SUCCESS && current+1<tasks.size())
+       {
+               // The task succeeded and there's more to run
+               ++current;
+               tasks[current]->start();
+               return true;
+       }
+
+       if(sub_status!=RUNNING)
+       {
+               // The task is not running anymore and either failed or was the last one
+               current = tasks.size();
+               final_status = sub_status;
+       }
+
+       return false;
+}
diff --git a/source/chainedtask.h b/source/chainedtask.h
new file mode 100644 (file)
index 0000000..2014f02
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef CHAINEDTASK_H_
+#define CHAINEDTASK_H_
+
+#include <vector>
+#include "task.h"
+
+/**
+Runs multiple tasks as one unit, one after the other.  Execution of the chain
+will stop if any of the component tasks terminates with an error.
+*/
+class ChainedTask: public Task
+{
+private:
+       std::vector<Task *> tasks;
+       unsigned current;
+       Status final_status;
+
+public:
+       ChainedTask(Task *);
+       ~ChainedTask();
+
+       void add_task(Task *);
+
+       virtual std::string get_command() const;
+       virtual void start();
+       virtual Status check();
+       virtual Status wait();
+private:
+       bool process(Status);
+};
+
+#endif