123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- /*
- * LoadProgress.cpp, part of VCMI engine
- *
- * Authors: listed in file AUTHORS in main folder
- *
- * License: GNU General Public License v2.0 or later
- * Full text of license available in license.txt file, in main folder
- *
- */
- #include "StdInc.h"
- #include "LoadProgress.h"
- using namespace Load;
- Progress::Progress()
- : Progress(100)
- {}
- Progress::Progress(int steps)
- : _progress(std::numeric_limits<Type>::min())
- , _target(std::numeric_limits<Type>::max())
- , _step(std::numeric_limits<Type>::min())
- , _maxSteps(steps)
- {
- }
- Type Progress::get() const
- {
- if(_step >= _maxSteps)
- return _target;
-
- if(!_maxSteps)
- return _progress;
-
- return static_cast<int>(_progress) + _step * static_cast<int>(_target - _progress) / _maxSteps;
- }
- void Progress::set(Type p)
- {
- _progress = p;
- }
- bool Progress::finished() const
- {
- return get() == std::numeric_limits<Type>::max();
- }
- void Progress::reset(int s)
- {
- _progress = std::numeric_limits<Type>::min();
- setupSteps(s);
- }
- void Progress::finish()
- {
- _progress = _target = std::numeric_limits<Type>::max();
- _step = std::numeric_limits<Type>::min();
- _maxSteps = std::numeric_limits<Type>::min();
- }
- void Progress::setupSteps(int s)
- {
- setupStepsTill(s, std::numeric_limits<Type>::max());
- }
- void Progress::setupStepsTill(int s, Type p)
- {
- if(finished())
- return;
-
- if(_step > std::numeric_limits<Type>::min())
- _progress = get();
-
- _step = std::numeric_limits<Type>::min();
- _maxSteps = s;
-
- _target = p;
- }
- void Progress::step(int count)
- {
- if(_step + count > _maxSteps)
- {
- _step = _maxSteps.load();
- }
- else
- {
- _step += count;
- }
- }
- void ProgressAccumulator::include(const Progress & p)
- {
- std::unique_lock<std::mutex> guard(_mx);
- _progress.emplace_back(p);
- }
- void ProgressAccumulator::exclude(const Progress & p)
- {
- std::unique_lock<std::mutex> guard(_mx);
- for(auto i = _progress.begin(); i != _progress.end(); ++i)
- {
- if(&i->get() == &p)
- {
- _accumulated += static_cast<long long>(p.get()) * p._maxSteps;
- _steps += p._maxSteps;
- _progress.erase(i);
- return;
- }
- }
- }
- bool ProgressAccumulator::finished() const
- {
- std::unique_lock<std::mutex> guard(_mx);
- for(auto i : _progress)
- if(!i.get().finished())
- return false;
- return true;
- }
- Type ProgressAccumulator::get() const
- {
- std::unique_lock<std::mutex> guard(_mx);
- auto sum = _accumulated;
- auto totalSteps = _steps;
- for(auto p : _progress)
- {
- sum += static_cast<long long>(p.get().get()) * p.get()._maxSteps;
- totalSteps += p.get()._maxSteps;
- }
-
- if(totalSteps)
- sum /= totalSteps;
- return static_cast<Type>(sum);
- }
|