AppInstallerProgress.h (5036B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #pragma once 4 #include <wil/resource.h> 5 #include <atomic> 6 #include <functional> 7 #include <string_view> 8 9 namespace AppInstaller 10 { 11 // Forward declaration 12 struct ProgressCallback; 13 struct IProgressCallback; 14 15 namespace details 16 { 17 // For SetCancellationFunction return. 18 inline void RemoveCancellationFunction(IProgressCallback* callback); 19 } 20 21 // The semantic meaning of the progress values. 22 enum class ProgressType : uint32_t 23 { 24 // Progress will not be sent. 25 None, 26 Bytes, 27 Percent, 28 }; 29 30 // The reason why progress is cancelled. 31 enum class CancelReason : uint32_t 32 { 33 None = 0x0, 34 Abort = 0x1, 35 CtrlCSignal = 0x2, 36 User = Abort | CtrlCSignal, 37 AppShutdown = 0x4, 38 Any = 0xFFFFFFFF 39 }; 40 41 DEFINE_ENUM_FLAG_OPERATORS(CancelReason); 42 43 // Gets the HRESULT associated with the given reason. 44 HRESULT ToHRESULT(CancelReason reason); 45 46 // Interface that provides a callback to inform of cancellation. 47 struct ICancellable 48 { 49 // Inform of cancellation with provided reason. 50 // When `force` is true, it is expected to happen regardless of user intent. 51 virtual void Cancel(CancelReason reason, bool force) = 0; 52 }; 53 54 // Interface that only receives progress, and does not participate in cancellation. 55 // This allows a sink be simple, and let ProgressCallback handle the complications 56 // of cancel state. 57 struct IProgressSink 58 { 59 // Called as progress is made. 60 // If maximum is 0, the maximum is unknown. 61 virtual void OnProgress(uint64_t current, uint64_t maximum, ProgressType type) = 0; 62 63 // Sets a message for the current progress state. 64 virtual void SetProgressMessage(std::string_view message) = 0; 65 66 // Called as progress begins. 67 virtual void BeginProgress() = 0; 68 69 // Called as progress ends. 70 virtual void EndProgress(bool hideProgressWhenDone) = 0; 71 }; 72 73 // Callback interface given to the worker to report to. 74 // Also enables the caller to request cancellation. 75 struct IProgressCallback : public IProgressSink 76 { 77 using CancelFunctionRemoval = wil::unique_any<IProgressCallback*, decltype(&details::RemoveCancellationFunction), details::RemoveCancellationFunction>; 78 79 // Returns a value indicating if the future has been cancelled. 80 virtual bool IsCancelledBy(CancelReason cancelReasons) = 0; 81 82 // Sets a cancellation function that will be called when the operation is to be cancelled. 83 [[nodiscard]] virtual CancelFunctionRemoval SetCancellationFunction(std::function<void()>&& f) = 0; 84 }; 85 86 // Implementation of IProgressCallback. 87 struct ProgressCallback : public IProgressCallback 88 { 89 ProgressCallback() = default; 90 ProgressCallback(IProgressSink* sink); 91 92 static bool Wait(IProgressCallback& progress, std::chrono::milliseconds ms); 93 94 void BeginProgress() override; 95 96 void OnProgress(uint64_t current, uint64_t maximum, ProgressType type) override; 97 98 void SetProgressMessage(std::string_view message) override; 99 100 void EndProgress(bool hideProgressWhenDone) override; 101 102 bool IsCancelledBy(CancelReason cancelReasons) override; 103 104 [[nodiscard]] IProgressCallback::CancelFunctionRemoval SetCancellationFunction(std::function<void()>&& f) override; 105 106 void Cancel(CancelReason reason = CancelReason::Abort); 107 108 IProgressSink* GetSink(); 109 110 private: 111 std::atomic<IProgressSink*> m_sink = nullptr; 112 std::function<void()> m_cancellationFunction; 113 CancelReason m_cancelReason = CancelReason::None; 114 }; 115 116 // A progress callback that reports its progress as a partial range of percentage to its base progress callback 117 struct PartialPercentProgressCallback : public ProgressCallback 118 { 119 PartialPercentProgressCallback(IProgressCallback& baseCallback, uint64_t globalMax); 120 121 void BeginProgress() override; 122 123 void OnProgress(uint64_t current, uint64_t maximum, ProgressType type) override; 124 125 void SetProgressMessage(std::string_view message) override; 126 127 void EndProgress(bool hideProgressWhenDone) override; 128 129 [[nodiscard]] IProgressCallback::CancelFunctionRemoval SetCancellationFunction(std::function<void()>&& f) override; 130 131 void SetRange(uint64_t rangeMin, uint64_t rangeMax); 132 133 private: 134 IProgressCallback& m_baseCallback; 135 uint64_t m_rangeMin = 0; 136 uint64_t m_rangeMax = 0; 137 uint64_t m_globalMax = 0; 138 }; 139 140 namespace details 141 { 142 inline void RemoveCancellationFunction(IProgressCallback* callback) 143 { 144 (void)callback->SetCancellationFunction(nullptr); 145 } 146 } 147 }