Tag Parser  7.0.3
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
progressfeedback.h
Go to the documentation of this file.
1 #ifndef TAGPARSER_PROGRESS_FEEDBACK_H
2 #define TAGPARSER_PROGRESS_FEEDBACK_H
3 
4 #include "./exceptions.h"
5 
6 #include <c++utilities/conversion/types.h>
7 
8 #include <atomic>
9 #include <functional>
10 #include <string>
11 
12 namespace TagParser {
13 
14 template <typename ActualProgressFeedback> class BasicProgressFeedback {
15 public:
16  using Callback = std::function<void(ActualProgressFeedback &feedback)>;
17 
18  BasicProgressFeedback(const Callback &callback, const Callback &percentageOnlyCallback = Callback());
19  BasicProgressFeedback(Callback &&callback, Callback &&percentageOnlyCallback = Callback());
20 
21  const std::string &step() const;
22  byte stepPercentage() const;
23  byte overallPercentage() const;
24  void updateStep(const std::string &step, byte stepPercentage = 0);
25  void updateStep(std::string &&step, byte stepPercentage = 0);
29 
30 private:
31  Callback m_callback;
32  Callback m_percentageOnlyCallback;
33  std::string m_step;
34  byte m_stepPercentage;
35  byte m_overallPercentage;
36 };
37 
38 template <typename ActualProgressFeedback>
39 inline BasicProgressFeedback<ActualProgressFeedback>::BasicProgressFeedback(const Callback &callback, const Callback &percentageOnlyCallback)
40  : m_callback(callback)
41  , m_percentageOnlyCallback(percentageOnlyCallback)
42  , m_stepPercentage(0)
43  , m_overallPercentage(0)
44 {
45 }
46 
47 template <typename ActualProgressFeedback>
49  : m_callback(callback)
50  , m_percentageOnlyCallback(percentageOnlyCallback)
51  , m_stepPercentage(0)
52  , m_overallPercentage(0)
53 {
54 }
55 
56 template <typename ActualProgressFeedback> inline const std::string &BasicProgressFeedback<ActualProgressFeedback>::step() const
57 {
58  return m_step;
59 }
60 
61 template <typename ActualProgressFeedback> inline byte BasicProgressFeedback<ActualProgressFeedback>::stepPercentage() const
62 {
63  return m_stepPercentage;
64 }
65 
66 template <typename ActualProgressFeedback> inline byte BasicProgressFeedback<ActualProgressFeedback>::overallPercentage() const
67 {
68  return m_overallPercentage;
69 }
70 
71 template <typename ActualProgressFeedback>
72 inline void BasicProgressFeedback<ActualProgressFeedback>::updateStep(const std::string &step, byte stepPercentage)
73 {
74  m_step = step;
75  m_stepPercentage = stepPercentage;
76  if (m_callback) {
77  m_callback(*static_cast<ActualProgressFeedback *>(this));
78  }
79 }
80 
81 template <typename ActualProgressFeedback>
82 inline void BasicProgressFeedback<ActualProgressFeedback>::updateStep(std::string &&step, byte stepPercentage)
83 {
84  m_step = step;
85  m_stepPercentage = stepPercentage;
86  if (m_callback) {
87  m_callback(*static_cast<ActualProgressFeedback *>(this));
88  }
89 }
90 
91 template <typename ActualProgressFeedback> inline void BasicProgressFeedback<ActualProgressFeedback>::updateStepPercentage(byte stepPercentage)
92 {
93  m_stepPercentage = stepPercentage;
94  if (m_percentageOnlyCallback) {
95  m_percentageOnlyCallback(*static_cast<ActualProgressFeedback *>(this));
96  } else if (m_callback) {
97  m_callback(*static_cast<ActualProgressFeedback *>(this));
98  }
99 }
100 
101 template <typename ActualProgressFeedback>
103 {
104  updateStepPercentage(static_cast<byte>(stepPercentage * 100.0));
105 }
106 
107 template <typename ActualProgressFeedback> inline void BasicProgressFeedback<ActualProgressFeedback>::updateOverallPercentage(byte overallPercentage)
108 {
109  m_overallPercentage = overallPercentage;
110  if (m_percentageOnlyCallback) {
111  m_percentageOnlyCallback(*static_cast<ActualProgressFeedback *>(this));
112  } else if (m_callback) {
113  m_callback(*static_cast<ActualProgressFeedback *>(this));
114  }
115 }
116 
117 class ProgressFeedback : public BasicProgressFeedback<ProgressFeedback> {
118  ProgressFeedback(const Callback &callback, const Callback &percentageOnlyCallback = Callback());
119  ProgressFeedback(Callback &&callback, Callback &&percentageOnlyCallback = Callback());
120 };
121 
122 inline ProgressFeedback::ProgressFeedback(const Callback &callback, const Callback &percentageOnlyCallback)
123  : BasicProgressFeedback<ProgressFeedback>(callback, percentageOnlyCallback)
124 {
125 }
126 
127 inline ProgressFeedback::ProgressFeedback(Callback &&callback, Callback &&percentageOnlyCallback)
128  : BasicProgressFeedback<ProgressFeedback>(callback, percentageOnlyCallback)
129 {
130 }
131 
132 class AbortableProgressFeedback : public BasicProgressFeedback<AbortableProgressFeedback> {
133 public:
134  AbortableProgressFeedback(const Callback &callback, const Callback &percentageOnlyCallback = Callback());
135  AbortableProgressFeedback(Callback &&callback, Callback &&percentageOnlyCallback = Callback());
136 
137  bool isAborted() const;
138  void tryToAbort();
139  void stopIfAborted() const;
140  void nextStepOrStop(const std::string &step, byte stepPercentage = 0);
141  void nextStepOrStop(std::string &&step, byte stepPercentage = 0);
142 
143 private:
144  std::atomic_bool m_aborted;
145 };
146 
147 inline AbortableProgressFeedback::AbortableProgressFeedback(const Callback &callback, const Callback &percentageOnlyCallback)
148  : BasicProgressFeedback<AbortableProgressFeedback>(callback, percentageOnlyCallback)
149  , m_aborted(false)
150 {
151 }
152 
153 inline AbortableProgressFeedback::AbortableProgressFeedback(Callback &&callback, Callback &&percentageOnlyCallback)
154  : BasicProgressFeedback<AbortableProgressFeedback>(callback, percentageOnlyCallback)
155  , m_aborted(false)
156 {
157 }
158 
160 {
161  return m_aborted.load();
162 }
163 
165 {
166  return m_aborted.store(true);
167 }
168 
170 {
171  if (isAborted()) {
173  }
174 }
175 
176 inline void AbortableProgressFeedback::nextStepOrStop(const std::string &status, byte percentage)
177 {
178  if (isAborted()) {
180  }
181  updateStep(status, percentage);
182 }
183 
184 inline void AbortableProgressFeedback::nextStepOrStop(std::string &&status, byte percentage)
185 {
186  if (isAborted()) {
188  }
189  updateStep(status, percentage);
190 }
191 
192 } // namespace TagParser
193 
194 #endif // TAGPARSER_PROGRESS_FEEDBACK_H
void updateStepPercentage(byte stepPercentage)
std::function< void(AbortableProgressFeedback &feedback)> Callback
BasicProgressFeedback(const Callback &callback, const Callback &percentageOnlyCallback=Callback())
void updateStepPercentageFromFraction(double stepPercentage)
AbortableProgressFeedback(const Callback &callback, const Callback &percentageOnlyCallback=Callback())
void updateOverallPercentage(byte overallPercentage)
void updateStep(const std::string &step, byte stepPercentage=0)
const std::string & step() const
void nextStepOrStop(const std::string &step, byte stepPercentage=0)