2
0

LoadProgress.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * LoadProgress.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "LoadProgress.h"
  12. using namespace Load;
  13. Progress::Progress()
  14. : Progress(100)
  15. {}
  16. Progress::Progress(int steps)
  17. : _progress(std::numeric_limits<Type>::min())
  18. , _target(std::numeric_limits<Type>::max())
  19. , _step(std::numeric_limits<Type>::min())
  20. , _maxSteps(steps)
  21. {
  22. }
  23. Type Progress::get() const
  24. {
  25. if(_step >= _maxSteps)
  26. return _target;
  27. if(!_maxSteps)
  28. return _progress;
  29. return static_cast<int>(_progress) + _step * static_cast<int>(_target - _progress) / _maxSteps;
  30. }
  31. void Progress::set(Type p)
  32. {
  33. _progress = p;
  34. }
  35. bool Progress::finished() const
  36. {
  37. return get() == std::numeric_limits<Type>::max();
  38. }
  39. void Progress::reset(int s)
  40. {
  41. _progress = std::numeric_limits<Type>::min();
  42. setupSteps(s);
  43. }
  44. void Progress::finish()
  45. {
  46. _progress = _target = std::numeric_limits<Type>::max();
  47. _step = std::numeric_limits<Type>::min();
  48. _maxSteps = std::numeric_limits<Type>::min();
  49. }
  50. void Progress::setupSteps(int s)
  51. {
  52. setupStepsTill(s, std::numeric_limits<Type>::max());
  53. }
  54. void Progress::setupStepsTill(int s, Type p)
  55. {
  56. if(finished())
  57. return;
  58. if(_step > std::numeric_limits<Type>::min())
  59. _progress = get();
  60. _step = std::numeric_limits<Type>::min();
  61. _maxSteps = s;
  62. _target = p;
  63. }
  64. void Progress::step(int count)
  65. {
  66. if(_step + count > _maxSteps)
  67. {
  68. _step = _maxSteps.load();
  69. }
  70. else
  71. {
  72. _step += count;
  73. }
  74. }
  75. void ProgressAccumulator::include(const Progress & p)
  76. {
  77. std::unique_lock<std::mutex> guard(_mx);
  78. _progress.emplace_back(p);
  79. }
  80. void ProgressAccumulator::exclude(const Progress & p)
  81. {
  82. std::unique_lock<std::mutex> guard(_mx);
  83. for(auto i = _progress.begin(); i != _progress.end(); ++i)
  84. {
  85. if(&i->get() == &p)
  86. {
  87. _accumulated += static_cast<long long>(p.get()) * p._maxSteps;
  88. _steps += p._maxSteps;
  89. _progress.erase(i);
  90. return;
  91. }
  92. }
  93. }
  94. bool ProgressAccumulator::finished() const
  95. {
  96. std::unique_lock<std::mutex> guard(_mx);
  97. for(auto i : _progress)
  98. if(!i.get().finished())
  99. return false;
  100. return true;
  101. }
  102. Type ProgressAccumulator::get() const
  103. {
  104. std::unique_lock<std::mutex> guard(_mx);
  105. auto sum = _accumulated;
  106. auto totalSteps = _steps;
  107. for(auto p : _progress)
  108. {
  109. sum += static_cast<long long>(p.get().get()) * p.get()._maxSteps;
  110. totalSteps += p.get()._maxSteps;
  111. }
  112. if(totalSteps)
  113. sum /= totalSteps;
  114. return static_cast<Type>(sum);
  115. }