Update wrt-commons_0.2.53
[framework/web/wrt-commons.git] / modules / core / include / dpl / task.h
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /*
17  * @file    task.h
18  * @author  Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
19  * @author  Radoslaw Wicik (r.wicik@samsung.com)
20  * @version 1.0
21  * @brief   Header file for abstaract task definition
22  */
23 #ifndef DPL_TASK_H
24 #define DPL_TASK_H
25
26 #include <dpl/noncopyable.h>
27 #include <dpl/foreach.h>
28 #include <dpl/assert.h>
29 #include <algorithm>
30 #include <list>
31
32 namespace DPL
33 {
34 class TaskList;
35
36 class Task
37     : private Noncopyable
38 {
39 public:
40     virtual ~Task() {}
41
42     virtual bool NextStep() = 0;
43     virtual bool Abort() = 0;
44     virtual size_t GetStepCount() const = 0;
45 };
46
47 template<typename Impl>
48 class TaskDecl
49     : public Task
50 {
51 protected:
52     typedef void (Impl::*Step)();
53
54 private:
55     typedef std::list<Step> StepList;
56
57     StepList m_steps;
58     StepList m_abortSteps;
59     typename StepList::iterator m_currentStep;
60     typename StepList::iterator m_nextStep;
61     bool m_switched;
62
63     Impl *m_impl;
64     bool m_running;
65
66 protected:
67     void AddStep(Step step)
68     {
69         Assert(!m_running && "AddStep is not allowed after calling NextStep!");
70         Assert(m_steps.end() == std::find(m_steps.begin(), m_steps.end(), step) && "The same step started twice is not supported");
71         m_steps.push_back(step);
72         m_nextStep = m_steps.begin();
73     }
74
75     void AddAbortStep(Step step)
76     {
77         Assert(!m_running && "AddAbortStep is not allowed after calling NextStep!");
78         Assert(m_abortSteps.end() == std::find(m_abortSteps.begin(), m_abortSteps.end(), step) && "The same step started twice is not supported");
79         m_abortSteps.push_front(step);
80     }
81
82     void SwitchToStep(Step step)
83     {
84         /// @TODO There can be problem here if user sets the same method two times in task list.
85         typename StepList::iterator i = std::find(m_steps.begin(), m_steps.end(), step);
86         Assert(i != m_steps.end());
87         m_nextStep = i;
88         m_switched = true;
89     }
90
91     Step GetCurrentStep() const
92     {
93         if(m_currentStep == m_steps.end())
94             return NULL;
95
96         return *m_currentStep;
97     }
98
99 public:
100     TaskDecl(Impl *impl)
101         : m_switched(false),
102           m_impl(impl),
103           m_running(false)
104     {
105         Assert(this == m_impl);
106         m_currentStep = m_steps.end();
107         m_nextStep = m_steps.end();
108     }
109
110     bool NextStep()
111     {
112         m_running = true;
113
114         Assert(m_nextStep != m_steps.end() && "Step list is empty or all steps done");
115
116         m_switched = false;
117
118         Step call = *m_nextStep;
119         (*m_impl.*call)();
120
121         m_currentStep = m_nextStep;
122
123         if (m_switched)
124             return true;
125         else
126             return ++m_nextStep != m_steps.end();
127     }
128
129     bool Abort()
130     {
131         m_running = true;
132
133         m_steps.clear();
134
135         if (m_abortSteps.empty())
136             return false;
137
138         FOREACH (it, m_abortSteps)
139             m_steps.push_back(*it);
140
141         m_nextStep = m_steps.begin();
142
143         m_abortSteps.clear();
144
145         return true;
146     }
147
148     size_t GetStepCount() const
149     {
150         return static_cast<size_t>(m_steps.size());
151     }
152 };
153 } // namespace DPL
154
155 #endif // DPL_TASK_H