progress.h 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. // 7-Zip work drives extraction; directory promotion, registration, and cleanup use bounded estimates.
  2. #pragma once
  3. #include <algorithm>
  4. #include <cmath>
  5. #include <cstdint>
  6. struct InstallProgress {
  7. int stage = 0;
  8. double value = 0;
  9. double target = 0;
  10. double from = 0;
  11. std::uint64_t stageStarted;
  12. std::uint64_t animationStarted;
  13. bool succeeded = false;
  14. explicit InstallProgress(std::uint64_t now) : stageStarted(now), animationStarted(now) {}
  15. void Tick(std::uint64_t now) {
  16. const double duration = succeeded ? 600.0 : 250.0;
  17. const double fraction = std::min(1.0, (now - animationStarted) / duration);
  18. value = from + (target - from) * fraction;
  19. }
  20. void Advance(int nextStage, double fraction, std::uint64_t now) {
  21. Tick(now);
  22. if (succeeded || nextStage < stage || nextStage > 4) return;
  23. if (nextStage > stage) {
  24. stage = nextStage;
  25. stageStarted = now;
  26. }
  27. const double boundaries[] = {0, 2, 94, 96, 98, 99};
  28. if (stage != 1) {
  29. const double seconds = stage == 0 ? 3.0 : stage == 4 ? 11.0 : 1.0;
  30. fraction = 1 - std::exp(-static_cast<double>(now - stageStarted) / (seconds * 1000));
  31. }
  32. const double next = boundaries[stage] + (boundaries[stage + 1] - boundaries[stage]) *
  33. std::max(0.0, std::min(1.0, fraction));
  34. if (next > target) {
  35. from = value;
  36. target = next;
  37. animationStarted = now;
  38. }
  39. }
  40. // Only the successful NSIS finish callback may authorize 100%.
  41. void Complete(std::uint64_t now) {
  42. if (succeeded) return;
  43. Tick(now);
  44. succeeded = true;
  45. from = value;
  46. target = 100;
  47. animationStarted = now;
  48. }
  49. int CaptionStage() const {
  50. const double boundaries[] = {0, 2, 94, 96, 98};
  51. int caption = 0;
  52. while (caption < stage && value >= boundaries[caption + 1]) ++caption;
  53. return caption;
  54. }
  55. };