The escape sequence that brings the screen up to date.
Only rows whose text changed since the last render are emitted, each as a move, a line clear and the text. One string comes back and the caller writes it once: a single write cannot tear, where a write per row can.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(frame_t), | intent(inout) | :: | this |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer(kind=default_int), | private | :: | i |
function frame_render(this) result(output) !! The escape sequence that brings the screen up to date. !! !! Only rows whose text changed since the last render are emitted, each !! as a move, a line clear and the text. One string comes back and the !! caller writes it once: a single write cannot tear, where a write per !! row can. class(frame_t), intent(inout) :: this character(len=:), allocatable :: output integer(default_int) :: i output = "" if (this%rows == 0_default_int) then this%full_redraw = .false. return end if do i = 1_default_int, this%rows if (.not. this%full_redraw) then ! Compared through `char` with an explicit length test. ! `string_type`'s `==` is Fortran character comparison, which pads ! the shorter side with blanks, so "abc" and "abc " compare ! equal. Those are the same text but not the same row: with a ! background colour still open at the end of the line, the three ! extra cells are painted. if (len(char(this%current(i))) == len(char(this%shown(i)))) then if (char(this%current(i)) == char(this%shown(i))) cycle end if end if output = output//ansi_move_to(i, 1_default_int)//ansi_clear_line()// & char(this%current(i)) this%shown(i) = this%current(i) end do this%full_redraw = .false. end function frame_render