From d82c27075546df82bf721d2227da6dec49c6ead9 Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Sun, 3 Dec 2023 17:36:26 -0800 Subject: [PATCH] More refactoring, common cell buffer --- console_win.go | 23 ++++------------------- screen.go | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- simulation.go | 30 +++++------------------------- tscreen.go | 27 ++++----------------------- wscreen.go | 23 ++++------------------- 5 files changed, 63 insertions(+), 89 deletions(-) diff --git a/console_win.go b/console_win.go index 89542651..3c47f90b 100644 --- a/console_win.go +++ b/console_win.go @@ -894,21 +894,6 @@ func (s *cScreen) mapStyle(style Style) uint16 { return attr } -func (s *cScreen) SetContent(x, y int, primary rune, combining []rune, style Style) { - s.Lock() - if !s.fini { - s.cells.SetContent(x, y, primary, combining, style) - } - s.Unlock() -} - -func (s *cScreen) GetContent(x, y int) (rune, []rune, Style, int) { - s.Lock() - primary, combining, style, width := s.cells.GetContent(x, y) - s.Unlock() - return primary, combining, style, width -} - func (s *cScreen) sendVtStyle(style Style) { esc := &strings.Builder{} @@ -1146,10 +1131,6 @@ func (s *cScreen) resize() { _ = s.PostEvent(NewEventResize(w, h)) } -func (s *cScreen) Fill(r rune, style Style) { - s.cells.Fill(r, style) -} - func (s *cScreen) clearScreen(style Style, vtEnable bool) { if vtEnable { s.sendVtStyle(style) @@ -1328,3 +1309,7 @@ func (s *cScreen) LockRegion(x, y, width, height int, lock bool) { func (s *cScreen) Tty() (Tty, bool) { return nil, false } + +func (s *cScreen) GetCells() *CellBuffer { + return &s.cells +} diff --git a/screen.go b/screen.go index 086361f7..a8fc0965 100644 --- a/screen.go +++ b/screen.go @@ -14,6 +14,8 @@ package tcell +import "sync" + // Screen represents the physical (or emulated) screen. // This can be a terminal window or a physical console. Platforms implement // this differently. @@ -307,9 +309,6 @@ const ( type screenImpl interface { Init() error Fini() - Fill(rune, Style) - GetContent(x, y int) (primary rune, combining []rune, style Style, width int) - SetContent(x int, y int, primary rune, combining []rune, style Style) SetStyle(style Style) ShowCursor(x int, y int) HideCursor() @@ -342,6 +341,17 @@ type screenImpl interface { SetSize(int, int) LockRegion(x, y, width, height int, lock bool) Tty() (Tty, bool) + + // Following methods are not part of the Screen api, but are used for interaction with + // the common layer code. + + // Locker locks the underlying data structures so that we can access them + // in a thread-safe way. + sync.Locker + + // GetCells returns a pointer to the underlying CellBuffer that the implementation uses. + // Various methods will write to these for performance, but will use the lock to do so. + GetCells() *CellBuffer } type baseScreen struct { @@ -359,3 +369,36 @@ func (b *baseScreen) SetCell(x int, y int, style Style, ch ...rune) { func (b *baseScreen) Clear() { b.Fill(' ', StyleDefault) } + +func (b *baseScreen) Fill(r rune, style Style) { + cb := b.GetCells() + b.Lock() + for i := range cb.cells { + c := &cb.cells[i] + c.currMain = r + c.currComb = nil + c.currStyle = style + c.width = 1 + } + b.Unlock() +} + +func (b *baseScreen) SetContent(x, y int, mainc rune, combc []rune, st Style) { + + cells := b.GetCells() + b.Lock() + cells.SetContent(x, y, mainc, combc, st) + b.Unlock() +} + +func (b *baseScreen) GetContent(x, y int) (rune, []rune, Style, int) { + var primary rune + var combining []rune + var style Style + var width int + cells := b.GetCells() + b.Lock() + primary, combining, style, width = cells.GetContent(x, y) + b.Unlock() + return primary, combining, style, width +} diff --git a/simulation.go b/simulation.go index ba7f441c..59ed7c12 100644 --- a/simulation.go +++ b/simulation.go @@ -1,4 +1,4 @@ -// Copyright 2022 The TCell Authors +// Copyright 2023 The TCell Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use file except in compliance with the License. @@ -149,30 +149,6 @@ func (s *simscreen) SetStyle(style Style) { s.Unlock() } -func (s *simscreen) Fill(r rune, style Style) { - s.Lock() - s.back.Fill(r, style) - s.Unlock() -} - -func (s *simscreen) SetContent(x, y int, mainc rune, combc []rune, st Style) { - - s.Lock() - s.back.SetContent(x, y, mainc, combc, st) - s.Unlock() -} - -func (s *simscreen) GetContent(x, y int) (rune, []rune, Style, int) { - var mainc rune - var combc []rune - var style Style - var width int - s.Lock() - mainc, combc, style, width = s.back.GetContent(x, y) - s.Unlock() - return mainc, combc, style, width -} - func (s *simscreen) drawCell(x, y int) int { mainc, combc, style, width := s.back.GetContent(x, y) @@ -558,3 +534,7 @@ func (s *simscreen) LockRegion(x, y, width, height int, lock bool) { func (s *simscreen) Tty() (Tty, bool) { return nil, false } + +func (s *simscreen) GetCells() *CellBuffer { + return &s.back +} diff --git a/tscreen.go b/tscreen.go index f3b64394..35ca147b 100644 --- a/tscreen.go +++ b/tscreen.go @@ -595,29 +595,6 @@ func (t *tScreen) SetStyle(style Style) { t.Unlock() } -func (t *tScreen) Fill(r rune, style Style) { - t.Lock() - if !t.fini { - t.cells.Fill(r, style) - } - t.Unlock() -} - -func (t *tScreen) SetContent(x, y int, mainc rune, combc []rune, style Style) { - t.Lock() - if !t.fini { - t.cells.SetContent(x, y, mainc, combc, style) - } - t.Unlock() -} - -func (t *tScreen) GetContent(x, y int) (rune, []rune, Style, int) { - t.Lock() - mainc, combc, style, width := t.cells.GetContent(x, y) - t.Unlock() - return mainc, combc, style, width -} - func (t *tScreen) encodeRune(r rune, buf []byte) []byte { nb := make([]byte, 6) @@ -1960,3 +1937,7 @@ func (t *tScreen) finalize() { t.disengage() _ = t.tty.Close() } + +func (t *tScreen) GetCells() *CellBuffer { + return &t.cells +} diff --git a/wscreen.go b/wscreen.go index 4e28f2e8..8c31b42c 100644 --- a/wscreen.go +++ b/wscreen.go @@ -79,25 +79,6 @@ func (t *wScreen) SetStyle(style Style) { t.Unlock() } -func (t *wScreen) Fill(r rune, style Style) { - t.Lock() - t.cells.Fill(r, style) - t.Unlock() -} - -func (t *wScreen) SetContent(x, y int, mainc rune, combc []rune, style Style) { - t.Lock() - t.cells.SetContent(x, y, mainc, combc, style) - t.Unlock() -} - -func (t *wScreen) GetContent(x, y int) (rune, []rune, Style, int) { - t.Lock() - mainc, combc, style, width := t.cells.GetContent(x, y) - t.Unlock() - return mainc, combc, style, width -} - // paletteColor gives a more natural palette color actually matching // typical XTerm. We might in the future want to permit styling these // via CSS. @@ -569,6 +550,10 @@ func (t *wScreen) Tty() (Tty, bool) { return nil, false } +func (t *wScreen) GetCells() *CellBuffer { + return &t.cells +} + // WebKeyNames maps string names reported from HTML // (KeyboardEvent.key) to tcell accepted keys. var WebKeyNames = map[string]Key{