winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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 }