Update bar.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(bar_object), | intent(inout) | :: | self | Bar. |
||
| real(kind=R8P), | intent(in) | :: | current | Current value. |
subroutine update(self, current)
!< Update bar.
class(bar_object), intent(inout) :: self !< Bar.
real(R8P), intent(in) :: current !< Current value.
integer(I4P) :: progress !< Progress, in percent.
integer(I4P), save :: progress_previous !< Previous progress, in percent.
integer(I8P), save :: tic_toc(1:2) !< Tic-toc timer.
integer(I4P), save :: spinner_count !< Spinner count.
character(len=18), save :: date_time_start !< Start date/time.
character(len=18) :: date_time !< Current date/time.
integer(I8P) :: count_rate !< Timer count rate.
integer(I4P) :: f_chars !< Number of filled characters of bar.
character(len=4, kind=UCS4) :: progress_percent !< Progress in percent.
character(len=12, kind=UCS4) :: progress_speed !< Progress speed in percent.
character(len=1, kind=UCS4), parameter :: bar_end=char(13) !< Last bar char, carriage return.
character(len=:, kind=UCS4), allocatable :: bar !< Bar line.
progress = nint(current / (self%max_value - self%min_value) * 100)
if (progress == 0) then
progress_previous = 0
spinner_count = 0
call system_clock(tic_toc(1), count_rate)
if (self%add_date_time) call date_and_time(date=date_time_start(1:8), time=date_time_start(9:))
endif
if (mod(progress, self%frequency) == 0 .or. progress == 100) then
call system_clock(tic_toc(2), count_rate)
f_chars = nint(progress / 100._R8P * self%width)
bar = achar(27)//'[?25l' ! hide cursor
bar = bar//self%prefix%output()
bar = bar//self%bracket_left%output()
bar = bar//repeat(self%filled_char%output(), f_chars)
bar = bar//repeat(self%empty_char%output(), self%width - f_chars)
bar = bar//self%bracket_right%output()
bar = bar//self%suffix%output()
if (allocated(self%spinner)) then
spinner_count = spinner_count + 1
if (spinner_count > size(self%spinner, dim=1)) spinner_count = 1
bar = bar//self%spinner(spinner_count)%output()
endif
if (self%add_progress_percent) then
write(progress_percent, '(I3,A)') progress, '%'
self%progress_percent%string = progress_percent
bar = bar//self%progress_percent%output()
endif
if (self%add_progress_speed) then
write(progress_speed, '(A,F6.2,A)') ' (', (progress - progress_previous) / &
(real(tic_toc(2) - tic_toc(1), kind=R8P) / count_rate), '%/s)'
self%progress_speed%string = progress_speed
bar = bar//self%progress_speed%output()
endif
bar = bar//bar_end
write(stdout, '(A)', advance='no') bar
flush(stdout)
progress_previous = progress
tic_toc(1) = tic_toc(2)
endif
if (progress >= 100) then
if (self%add_date_time) then
call date_and_time(date=date_time(1:8), time=date_time(9:))
self%date_time%string = '['//date_time_start(1:4)//'/'//date_time_start(5:6)//'/'//date_time_start(7:8)// &
' '//date_time_start(9:10)//':'//date_time_start(11:12)//':'//date_time_start(13:14)// &
' - '//date_time(1:4)//'/'//date_time(5:6)//'/'//date_time(7:8)// &
' '//date_time(9:10)//':'//date_time(11:12)//':'//date_time(13:14)//']'
write(stdout, '(A)') achar(27)//'[?25h' ! restore cursor
write(stdout, '(A)') self%date_time%output()
else
write(stdout, '(A)') achar(27)//'[?25h'! restore cursor
endif
self%is_stdout_locked_ = .false.
endif
endsubroutine update