master
cpp 112 lines 2.39 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 ConsoleProgressIndicator.cpp
8
9 Abstract:
10
11 This file contains the ConsoleProgressIndicator implementation
12
13 --*/
14
15 #include "precomp.h"
16 #include "ConsoleProgressIndicator.h"
17 #include "wslutil.h"
18
19 wsl::windows::common::ConsoleProgressIndicator::ConsoleProgressIndicator(std::wstring&& inputMessage, bool animatedDots)
20 {
21 m_waitMessage = std::move(inputMessage);
22
23 // Start the thread to update progress bar only if it's a tty
24 if (_isatty(_fileno(stderr)))
25 {
26 m_interactive = true;
27
28 if (animatedDots)
29 {
30 m_event.create(wil::EventOptions::ManualReset);
31 m_thread = std::thread([&] { IndicateProgress(); });
32 }
33 else
34 {
35 fwprintf(stderr, L"%ls", m_waitMessage.c_str());
36 }
37 }
38 }
39
40 wsl::windows::common::ConsoleProgressIndicator::~ConsoleProgressIndicator()
41 {
42 End();
43 }
44
45 void wsl::windows::common::ConsoleProgressIndicator::UpdateProgress(std::wstring&& Progress)
46 {
47 if (!m_interactive)
48 {
49 return;
50 }
51
52 // Only update if the new progress message differs from the previous one
53 if (Progress == m_progressMessage)
54 {
55 return;
56 }
57
58 for (auto i = 0; i < m_progressMessage.size(); i++)
59 {
60 fwprintf(stderr, L"\b \b");
61 }
62
63 fwprintf(stderr, L"%ls", Progress.c_str());
64 m_progressMessage = std::move(Progress);
65 }
66
67 void wsl::windows::common::ConsoleProgressIndicator::IndicateProgress() const
68 {
69 fwprintf(stderr, L"%ls", m_waitMessage.c_str());
70
71 // Print status until the exit event is signaled.
72 int currentDots = 0;
73 constexpr int c_maxDots = 3;
74 while (!m_event.wait(500))
75 {
76 if (currentDots < c_maxDots)
77 {
78 fwprintf(stderr, L".");
79 currentDots++;
80 }
81 else
82 {
83 for (int i = 0; i < c_maxDots; i++)
84 {
85 fwprintf(stderr, L"\b \b");
86 }
87
88 currentDots = 0;
89 }
90 }
91
92 // Clear any dots that remain.
93 for (int i = 0; i < currentDots; i++)
94 {
95 fwprintf(stderr, L"\b \b");
96 }
97 }
98
99 void wsl::windows::common::ConsoleProgressIndicator::End()
100 {
101 // If the thread started, trigger exit event and join thread.
102 if (m_thread.joinable())
103 {
104 m_event.SetEvent();
105 m_thread.join();
106 }
107
108 if (m_interactive)
109 {
110 fwprintf(stderr, L"\n");
111 }
112 }