xmscore  1.0
Progress.cpp
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
6 //------------------------------------------------------------------------------
7 
8 //----- Included files ---------------------------------------------------------
9 
10 // 1. Precompiled header
11 
12 // 2. My own header
13 #include <xmscore/misc/Progress.h>
14 
15 // 3. Standard library headers
16 
17 // 4. External library headers
18 
19 // 5. Shared code headers
20 #include <xmscore/misc/XmError.h>
21 
22 // 6. Non-shared code headers
23 
24 //----- Forward declarations ---------------------------------------------------
25 
26 //----- External globals -------------------------------------------------------
27 
28 //----- Namespace declaration --------------------------------------------------
29 namespace xms
30 {
31 //----- Constants / Enumerations -----------------------------------------------
32 
33 //----- Classes / Structs ------------------------------------------------------
34 
35 //----- Internal functions -----------------------------------------------------
36 
37 //----- Class / Function definitions -------------------------------------------
38 
39 //------------------------------------------------------------------------------
42 //------------------------------------------------------------------------------
43 BSHP<ProgressListener>& iListener()
44 {
45  static BSHP<ProgressListener> fg_listener;
46  return fg_listener;
47 } // iListener
48 
55 //------------------------------------------------------------------------------
58 //------------------------------------------------------------------------------
59 Progress::Progress(const std::string& a_message)
60 : m_stackIndex(0)
61 , m_itemCount(0)
62 {
63  if (iListener())
64  {
65  m_stackIndex = iListener()->OnBeginOperationString(a_message);
66  }
67 } // Progress::Progress
68 //------------------------------------------------------------------------------
70 //------------------------------------------------------------------------------
72 {
73  if (iListener())
74  {
75  iListener()->OnEndOperation(m_stackIndex);
76  }
77 } // Progress::~Progress
78 //------------------------------------------------------------------------------
81 //------------------------------------------------------------------------------
82 void Progress::UpdateMessage(const std::string& a_message)
83 {
84  if (iListener())
85  {
86  iListener()->OnUpdateMessage(m_stackIndex, a_message);
87  }
88 } // Progress::UpdateMessage
89 //------------------------------------------------------------------------------
92 //------------------------------------------------------------------------------
93 void Progress::SetItemCount(long long a_count)
94 {
95  m_itemCount = a_count;
96 } // Progress::SetItemCount
97 //------------------------------------------------------------------------------
101 //------------------------------------------------------------------------------
102 void Progress::CurrentItem(long long a_item)
103 {
104  XM_ASSERT(m_itemCount != 0);
105  if (iListener() && m_itemCount)
106  {
107  if (a_item < m_itemCount)
108  ++a_item;
109  iListener()->OnProgressStatus(m_stackIndex, (double)a_item / m_itemCount);
110  }
111 } // Progress::CurrentItem
112 //------------------------------------------------------------------------------
115 //------------------------------------------------------------------------------
116 void Progress::ProgressStatus(double a_fractionComplete)
117 {
118  // should use either this alone or SetItemCount/CurrentItem
119  XM_ASSERT(m_itemCount == 0);
120 
121  if (iListener())
122  {
123  iListener()->OnProgressStatus(m_stackIndex, a_fractionComplete);
124  }
125 } // Progress::ProgressStatus
126 
127 //------------------------------------------------------------------------------
129 //------------------------------------------------------------------------------
131 {
132 } // ProgressListener::~ProgressListener
133 //------------------------------------------------------------------------------
136 //------------------------------------------------------------------------------
137 void ProgressListener::SetListener(BSHP<ProgressListener> a_listener)
138 {
139  iListener() = a_listener;
140 } // ProgressListener::SetListener
141 //------------------------------------------------------------------------------
144 //------------------------------------------------------------------------------
145 BSHP<ProgressListener> ProgressListener::GetListener()
146 {
147  return iListener();
148 } // ProgressListener::GetListener
149 
150 } // namespace xms
151 
152 #ifdef CXX_TEST
153 #include <xmscore/misc/Progress.t.h>
154 #include <sstream>
155 
156 using namespace xms;
157 
161 {
162 public:
165 
166  //------------------------------------------------------------------------------
170  //------------------------------------------------------------------------------
171  void OnProgressStatus(int a_stackIndex, double a_fractionComplete) override
172  {
173  std::ostringstream ss;
174  ss << "OnProgressStatus " << a_stackIndex << ": " << a_fractionComplete << '\n';
175  m_messages += ss.str();
176  }
177  //------------------------------------------------------------------------------
181  //------------------------------------------------------------------------------
182  int OnBeginOperationString(const std::string& a_operation) override
183  {
184  ++m_stackIndex;
185  std::ostringstream ss;
186  ss << "OnBeginOperationString " << a_operation << '\n';
187  m_messages += ss.str();
188  return m_stackIndex;
189  }
190 
191  //------------------------------------------------------------------------------
194  //------------------------------------------------------------------------------
195  void OnEndOperation(int a_stackIndex) override
196  {
197  --m_stackIndex;
198  std::ostringstream ss;
199  ss << "OnEndOperation " << a_stackIndex << '\n';
200  m_messages += ss.str();
201  }
202 
203  //------------------------------------------------------------------------------
207  //------------------------------------------------------------------------------
208  void OnUpdateMessage(int a_stackIndex, const std::string& a_message) override
209  {
210  std::ostringstream ss;
211  ss << "OnUpdateMessage " << a_stackIndex << ": " << a_message << '\n';
212  m_messages += ss.str();
213  }
214 
215  std::string m_messages;
216  int m_stackIndex = 0;
217 };
222 //------------------------------------------------------------------------------
224 //------------------------------------------------------------------------------
226 {
227  BSHP<ProgressListener> old = ProgressListener::GetListener();
228  BSHP<MockProgressListener> listener(new MockProgressListener);
230  {
231  Progress p1("First progress");
232  p1.ProgressStatus(0.5);
233  {
234  {
235  Progress p2("Second progress");
236  p2.ProgressStatus(0.25);
237  p2.UpdateMessage("Second progress message 2");
238  p2.ProgressStatus(0.75);
239  }
240  {
241  Progress p3("Third progress");
242  p3.SetItemCount(4);
243  p3.CurrentItem(0);
244  p3.CurrentItem(1);
245  p3.CurrentItem(2);
246  p3.CurrentItem(3);
247  }
248  }
249  p1.ProgressStatus(1.0);
250  }
251 
252  std::string expected =
253  "OnBeginOperationString First progress\n"
254  "OnProgressStatus 1: 0.5\n"
255  "OnBeginOperationString Second progress\n"
256  "OnProgressStatus 2: 0.25\n"
257  "OnUpdateMessage 2: Second progress message 2\n"
258  "OnProgressStatus 2: 0.75\n"
259  "OnEndOperation 2\n"
260  "OnBeginOperationString Third progress\n"
261  "OnProgressStatus 2: 0.25\n"
262  "OnProgressStatus 2: 0.5\n"
263  "OnProgressStatus 2: 0.75\n"
264  "OnProgressStatus 2: 1\n"
265  "OnEndOperation 2\n"
266  "OnProgressStatus 1: 1\n"
267  "OnEndOperation 1\n";
268  TS_ASSERT_EQUALS(expected, listener->m_messages);
270 } // ProgressUnitTests::testProgress
271 
272 #endif
mock class to show how the Progress and ProgressListener classes work
Definition: Progress.cpp:160
Stack based class to give notification of progress for a long task. Progress can be stacked by making...
Definition: Progress.h:22
void CurrentItem(long long a_item)
Give notification for the number of items completed. Used with SetItemCount.
Definition: Progress.cpp:102
BSHP< ProgressListener > & iListener()
Get the current ProgressListener.
Definition: Progress.cpp:43
void UpdateMessage(const std::string &a_message)
Update the current progress message.
Definition: Progress.cpp:82
Progress(const std::string &a_message)
Constructor.
Definition: Progress.cpp:59
Listen to progress reported from Progress class.
Definition: Progress.h:42
void testProgress()
Test Progress class.
Definition: Progress.cpp:225
int OnBeginOperationString(const std::string &a_operation) override
Listen to when operation begins.
Definition: Progress.cpp:182
void OnUpdateMessage(int a_stackIndex, const std::string &a_message) override
Listen to when operation ends.
Definition: Progress.cpp:208
void OnEndOperation(int a_stackIndex) override
Listen to when operation ends.
Definition: Progress.cpp:195
void SetItemCount(long long a_count)
Set the number of items to be processed. Used with CurrentItem.
Definition: Progress.cpp:93
void ProgressStatus(double a_percentComplete)
Give notification for the progress percent complete.
Definition: Progress.cpp:116
#define XM_ASSERT(x)
Does a regular ASSERT if xmAsserting, otherwise does nothing.
Definition: XmError.h:69
~Progress()
Destructor.
Definition: Progress.cpp:71
std::string m_messages
stored up messages
Definition: Progress.cpp:215
int m_stackIndex
instances index on stack of instances
Definition: Progress.h:36
Functions and macros for assertion and checking for errors.
long long m_itemCount
number of items to process
Definition: Progress.h:37
void OnProgressStatus(int a_stackIndex, double a_fractionComplete) override
Listen to progress status.
Definition: Progress.cpp:171
static void SetListener(BSHP< ProgressListener > a_listener)
Set the current progress listener.
Definition: Progress.cpp:137
virtual ~ProgressListener()
Destructor.
Definition: Progress.cpp:130
static BSHP< ProgressListener > GetListener()
Get the current progress listener.
Definition: Progress.cpp:145