Sequencer.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025
00026 #ifndef _PreComp_
00027 # include <cstdio>
00028 # include <algorithm>
00029 # include <QMutex>
00030 # include <QMutexLocker>
00031 #endif
00032
00033 #include "Sequencer.h"
00034 #include "Console.h"
00035 #include <CXX/Objects.hxx>
00036
00037 using namespace Base;
00038
00039 namespace Base {
00040 struct SequencerP {
00041
00042 static std::vector<SequencerBase*> _instances;
00043 static SequencerLauncher* _topLauncher;
00044 static QMutex mutex;
00048 static void appendInstance (SequencerBase* s)
00049 {
00050 _instances.push_back(s);
00051 }
00052 static void removeInstance (SequencerBase* s)
00053 {
00054 std::vector<SequencerBase*>::iterator it;
00055 it = std::find(_instances.begin(), _instances.end(), s);
00056 _instances.erase(it);
00057 }
00058 static SequencerBase& getInstance ()
00059 {
00060 return *_instances.back();
00061 }
00062 };
00063
00068 std::vector<SequencerBase*> SequencerP::_instances;
00069 SequencerLauncher* SequencerP::_topLauncher = 0;
00070 QMutex SequencerP::mutex(QMutex::Recursive);
00071 };
00072
00073 SequencerBase& SequencerBase::Instance ()
00074 {
00075
00076 if (SequencerP::_instances.size() == 0) {
00077 new ConsoleSequencer();
00078 }
00079
00080 return SequencerP::getInstance();
00081 }
00082
00083 SequencerBase::SequencerBase()
00084 : nProgress(0), nTotalSteps(0), _bLocked(false), _bCanceled(false), _nLastPercentage(-1)
00085 {
00086 SequencerP::appendInstance(this);
00087 }
00088
00089 SequencerBase::~SequencerBase()
00090 {
00091 SequencerP::removeInstance(this);
00092 }
00093
00094 bool SequencerBase::start(const char* pszStr, size_t steps)
00095 {
00096
00097 this->_nLastPercentage = -1;
00098
00099 this->nTotalSteps = steps;
00100 this->nProgress = 0;
00101 this->_bCanceled = false;
00102
00103 setText(pszStr);
00104
00105
00106 if (!this->_bLocked)
00107 startStep();
00108
00109 return true;
00110 }
00111
00112 size_t SequencerBase::numberOfSteps() const
00113 {
00114 return this->nTotalSteps;
00115 }
00116
00117 void SequencerBase::startStep()
00118 {
00119 }
00120
00121 bool SequencerBase::next(bool canAbort)
00122 {
00123 this->nProgress++;
00124 float fDiv = this->nTotalSteps > 0 ? (float)this->nTotalSteps : 1000.0f;
00125 int perc = (int)((float)this->nProgress * (100.0f / fDiv));
00126
00127
00128 if (perc > this->_nLastPercentage) {
00129 this->_nLastPercentage = perc;
00130
00131
00132 if (!this->_bLocked)
00133 nextStep(canAbort);
00134 }
00135
00136 return this->nProgress < this->nTotalSteps;
00137 }
00138
00139 void SequencerBase::nextStep( bool )
00140 {
00141 }
00142
00143 void SequencerBase::setProgress(size_t)
00144 {
00145 }
00146
00147 bool SequencerBase::stop()
00148 {
00149 resetData();
00150 return true;
00151 }
00152
00153 void SequencerBase::pause()
00154 {
00155 }
00156
00157 void SequencerBase::resume()
00158 {
00159 }
00160
00161 bool SequencerBase::isBlocking() const
00162 {
00163 return true;
00164 }
00165
00166 bool SequencerBase::setLocked(bool bLocked)
00167 {
00168 QMutexLocker locker(&SequencerP::mutex);
00169 bool old = this->_bLocked;
00170 this->_bLocked = bLocked;
00171 return old;
00172 }
00173
00174 bool SequencerBase::isLocked() const
00175 {
00176 QMutexLocker locker(&SequencerP::mutex);
00177 return this->_bLocked;
00178 }
00179
00180 bool SequencerBase::isRunning() const
00181 {
00182 QMutexLocker locker(&SequencerP::mutex);
00183 return (SequencerP::_topLauncher != 0);
00184 }
00185
00186 bool SequencerBase::wasCanceled() const
00187 {
00188 QMutexLocker locker(&SequencerP::mutex);
00189 return this->_bCanceled;
00190 }
00191
00192 void SequencerBase::tryToCancel()
00193 {
00194 this->_bCanceled = true;
00195 }
00196
00197 void SequencerBase::rejectCancel()
00198 {
00199 this->_bCanceled = false;
00200 }
00201
00202 int SequencerBase::progressInPercent() const
00203 {
00204 return this->_nLastPercentage;
00205 }
00206
00207 void SequencerBase::resetData()
00208 {
00209 this->_bCanceled = false;
00210 }
00211
00212 void SequencerBase::setText(const char*)
00213 {
00214 }
00215
00216
00217
00218 EmptySequencer::EmptySequencer()
00219 {
00220 }
00221
00222 EmptySequencer::~EmptySequencer()
00223 {
00224 }
00225
00226
00227
00228 using Base::ConsoleSequencer;
00229
00230 ConsoleSequencer::ConsoleSequencer ()
00231 {
00232 }
00233
00234 ConsoleSequencer::~ConsoleSequencer ()
00235 {
00236 }
00237
00238 void ConsoleSequencer::setText (const char* pszTxt)
00239 {
00240 printf("%s...\n", pszTxt);
00241 }
00242
00243 void ConsoleSequencer::startStep()
00244 {
00245 }
00246
00247 void ConsoleSequencer::nextStep( bool )
00248 {
00249 if (this->nTotalSteps != 0)
00250 printf("\t\t\t\t\t\t(%2.1f %%)\t\r", (float)progressInPercent());
00251 }
00252
00253 void ConsoleSequencer::resetData()
00254 {
00255 SequencerBase::resetData();
00256 printf("\t\t\t\t\t\t\t\t\r");
00257 }
00258
00259
00260
00261 SequencerLauncher::SequencerLauncher(const char* pszStr, size_t steps)
00262 {
00263 QMutexLocker locker(&SequencerP::mutex);
00264
00265 if (!SequencerP::_topLauncher) {
00266 SequencerBase::Instance().start(pszStr, steps);
00267 SequencerP::_topLauncher = this;
00268 }
00269 }
00270
00271 SequencerLauncher::~SequencerLauncher()
00272 {
00273 QMutexLocker locker(&SequencerP::mutex);
00274 if (SequencerP::_topLauncher == this)
00275 SequencerBase::Instance().stop();
00276 if (SequencerP::_topLauncher == this) {
00277 SequencerP::_topLauncher = 0;
00278 }
00279 }
00280
00281 void SequencerLauncher::setText (const char* pszTxt)
00282 {
00283 QMutexLocker locker(&SequencerP::mutex);
00284 SequencerBase::Instance().setText(pszTxt);
00285 }
00286
00287 bool SequencerLauncher::next(bool canAbort)
00288 {
00289 QMutexLocker locker(&SequencerP::mutex);
00290 if (SequencerP::_topLauncher != this)
00291 return true;
00292 return SequencerBase::Instance().next(canAbort);
00293 }
00294
00295 void SequencerLauncher::setProgress(size_t pos)
00296 {
00297 QMutexLocker locker(&SequencerP::mutex);
00298 SequencerBase::Instance().setProgress(pos);
00299 }
00300
00301 size_t SequencerLauncher::numberOfSteps() const
00302 {
00303 QMutexLocker locker(&SequencerP::mutex);
00304 return SequencerBase::Instance().numberOfSteps();
00305 }
00306
00307 bool SequencerLauncher::wasCanceled() const
00308 {
00309 return SequencerBase::Instance().wasCanceled();
00310 }
00311
00312
00313
00314 void ProgressIndicatorPy::init_type()
00315 {
00316 behaviors().name("ProgressIndicator");
00317 behaviors().doc("Progress indicator");
00318
00319 behaviors().supportRepr();
00320 behaviors().supportGetattr();
00321 behaviors().supportSetattr();
00322 behaviors().type_object()->tp_new = &PyMake;
00323
00324 add_varargs_method("start",&ProgressIndicatorPy::start,"start(string,int)");
00325 add_varargs_method("next",&ProgressIndicatorPy::next,"next()");
00326 add_varargs_method("stop",&ProgressIndicatorPy::stop,"stop()");
00327 }
00328
00329 PyObject *ProgressIndicatorPy::PyMake(struct _typeobject *, PyObject *, PyObject *)
00330 {
00331 return new ProgressIndicatorPy();
00332 }
00333
00334 ProgressIndicatorPy::ProgressIndicatorPy()
00335 {
00336 }
00337
00338 ProgressIndicatorPy::~ProgressIndicatorPy()
00339 {
00340 }
00341
00342 Py::Object ProgressIndicatorPy::repr()
00343 {
00344 std::string s = "Base.ProgressIndicator";
00345 return Py::String(s);
00346 }
00347
00348 Py::Object ProgressIndicatorPy::start(const Py::Tuple& args)
00349 {
00350 char* text;
00351 int steps;
00352 if (!PyArg_ParseTuple(args.ptr(), "si",&text,&steps))
00353 throw Py::Exception();
00354 if (!_seq.get())
00355 _seq.reset(new SequencerLauncher(text,steps));
00356 return Py::None();
00357 }
00358
00359 Py::Object ProgressIndicatorPy::next(const Py::Tuple& args)
00360 {
00361 int b=0;
00362 if (!PyArg_ParseTuple(args.ptr(), "|i",&b))
00363 throw Py::Exception();
00364 if (_seq.get()) {
00365 try {
00366 _seq->next(b ? true : false);
00367 }
00368 catch (const Base::AbortException&) {
00369 _seq.reset();
00370 throw Py::Exception("abort progress indicator");
00371 }
00372 }
00373 return Py::None();
00374 }
00375
00376 Py::Object ProgressIndicatorPy::stop(const Py::Tuple& args)
00377 {
00378 if (!PyArg_ParseTuple(args.ptr(), ""))
00379 throw Py::Exception();
00380 _seq.reset();
00381 return Py::None();
00382 }