/
repeated_task.cpp
88 lines (72 loc) · 2.43 KB
/
repeated_task.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include "repeated_task.h"
RepeatedTask::RepeatedTask(char const* n, Task const& t, unsigned r) :
Task(n), repetitions(r), repetitionProgress(0), current(nullptr) {
prototype = (Task*)t.clone();
reset();
}
RepeatedTask::RepeatedTask(RepeatedTask const& rt) : Task(rt) {
copy(rt);
}
RepeatedTask& RepeatedTask::operator=(RepeatedTask const& rt) {
if (&rt != this) {
Task::operator=(rt);
destroy();
copy(rt);
}
return *this;
}
RepeatedTask::~RepeatedTask() {
destroy();
}
void RepeatedTask::copy(RepeatedTask const& rt) {
repetitions = rt.repetitions;
repetitionProgress = rt.repetitionProgress;
prototype = (Task*)rt.prototype->clone();
current = (Task*)rt.current->clone();
}
void RepeatedTask::destroy() {
delete prototype;
delete current;
}
void RepeatedTask::print(std::ostream& os) const {
os << "Повтаряща се ";
Task::print(os);
os << ", която повтаря " << repetitions << " пъти задачата: (";
current->print(os);
os << ") и вече са изпълнени " << repetitionProgress << " повторения";
}
unsigned RepeatedTask::getExecutionTime() const {
return repetitions * prototype->getExecutionTime();
}
unsigned RepeatedTask::getProgress() const {
return repetitionProgress * prototype->getExecutionTime() +
current->getProgress();
}
unsigned RepeatedTask::work(unsigned t) {
if (isFinished() || t == 0)
return t;
// фаза 1: довършваме текущата задача
t = current->work(t);
// ще има ли други фази?
if (!current->isFinished()) // не сме завършили текущата задача
return t;
// завършили сме текущата задача
repetitionProgress++;
reset();
// има ли още задачи и време?
if (isFinished())
// не
return t;
// има още задачи за повтаряне
// фаза 2: изпълняваме някакъв брой повторения на current
unsigned spentRepetitions = std::min(t / prototype->getExecutionTime(),
repetitions - repetitionProgress);
repetitionProgress += spentRepetitions;
t -= spentRepetitions * prototype->getExecutionTime();
// има ли още задачи?
if (isFinished() || t == 0)
// не
return t;
// фаза 3: изпълняваме докъдето можем current
return current->work(t);
}