Simplify the change tracker implementation a little
Since the cursor is always redrawn there is no need to track its attributes and position separately. Also no need to use a callback for dirtied status.
This commit is contained in:
parent
1b252be434
commit
c7b87f9174
@ -53,7 +53,7 @@ class Boss(Thread):
|
||||
self.queue_action(self.initialize)
|
||||
self.profile = args.profile
|
||||
self.window, self.opts = window, opts
|
||||
self.tracker = ChangeTracker(self.mark_dirtied)
|
||||
self.tracker = ChangeTracker()
|
||||
self.screen = Screen(self.opts, self.tracker, self)
|
||||
self.char_grid = CharGrid(self.screen, opts, window_width, window_height)
|
||||
sclass = DebugStream if args.dump_commands else Stream
|
||||
@ -179,6 +179,8 @@ class Boss(Thread):
|
||||
dispatch[r]()
|
||||
if writers:
|
||||
self.write_ready()
|
||||
if self.tracker.dirty:
|
||||
self.mark_dirtied()
|
||||
if self.pending_update_screen is not None and monotonic() > self.pending_update_screen:
|
||||
self.apply_update_screen()
|
||||
|
||||
|
||||
@ -246,7 +246,8 @@ class CharGrid:
|
||||
rd.cell_data = copy(self.sprite_map)
|
||||
rd.sprite_layout = self.sprites.layout
|
||||
c = changes.get('cursor')
|
||||
if c is not None:
|
||||
if c:
|
||||
c = self.screen.cursor
|
||||
rd.cursor = Cursor(c.x, c.y, c.hidden, c.shape, c.color, c.blink)
|
||||
self.render_queue.put(rd)
|
||||
|
||||
|
||||
@ -52,7 +52,7 @@ class Screen:
|
||||
for a description of the presentational component, implemented by ``Screen``.
|
||||
"""
|
||||
|
||||
tracker_callbacks = 'cursor_changed cursor_position_changed update_screen update_line_range update_cell_range line_added_to_history'.split()
|
||||
tracker_callbacks = 'cursor_changed update_screen update_line_range update_cell_range line_added_to_history'.split()
|
||||
_notify_cursor_position = True
|
||||
|
||||
def __init__(self, opts, tracker, callbacks=None, columns: int=80, lines: int=24):
|
||||
@ -86,7 +86,7 @@ class Screen:
|
||||
|
||||
def notify_cursor_position(self):
|
||||
if self._notify_cursor_position:
|
||||
self.cursor_position_changed(self.cursor)
|
||||
self.cursor_changed()
|
||||
|
||||
@property
|
||||
def display(self) -> Sequence[str]:
|
||||
@ -136,7 +136,7 @@ class Screen:
|
||||
self.normal_keypad_mode()
|
||||
|
||||
self.cursor = Cursor(0, 0)
|
||||
self.cursor_changed(self.cursor)
|
||||
self.cursor_changed()
|
||||
self.cursor_position()
|
||||
self.change_default_color('fg', None)
|
||||
self.change_default_color('bg', None)
|
||||
@ -235,7 +235,7 @@ class Screen:
|
||||
# Show/hide the cursor.
|
||||
previous, self.cursor.hidden = self.cursor.hidden, mo.DECTCEM not in self.mode
|
||||
if previous != self.cursor.hidden:
|
||||
self.cursor_changed(self.cursor)
|
||||
self.cursor_changed()
|
||||
|
||||
if mo.ALTERNATE_SCREEN in self.mode and self.linebuf is self.main_linebuf:
|
||||
self.toggle_screen_buffer()
|
||||
@ -279,7 +279,7 @@ class Screen:
|
||||
# Show/hide the cursor.
|
||||
previous, self.cursor.hidden = self.cursor.hidden, mo.DECTCEM not in self.mode
|
||||
if previous != self.cursor.hidden:
|
||||
self.cursor_changed(self.cursor)
|
||||
self.cursor_changed()
|
||||
|
||||
if mo.ALTERNATE_SCREEN not in self.mode and self.linebuf is not self.main_linebuf:
|
||||
self.toggle_screen_buffer()
|
||||
@ -543,7 +543,7 @@ class Screen:
|
||||
self.set_mode(mo.DECAWM)
|
||||
|
||||
self.cursor = savepoint.cursor
|
||||
self.cursor_changed(self.cursor)
|
||||
self.cursor_changed()
|
||||
self.ensure_bounds(use_margins=True)
|
||||
else:
|
||||
# If nothing was saved, the cursor moves to home position;
|
||||
@ -976,7 +976,7 @@ class Screen:
|
||||
shape = 'block' if mode < 3 else 'underline' if mode < 5 else 'beam' if mode < 7 else None
|
||||
if shape != self.cursor.shape or blink != self.cursor.blink:
|
||||
self.cursor.shape, self.cursor.blink = shape, blink
|
||||
self.cursor_changed(self.cursor)
|
||||
self.cursor_changed()
|
||||
elif secondary == '"': # DECSCA
|
||||
pass
|
||||
else: # DECLL
|
||||
@ -998,7 +998,7 @@ class Screen:
|
||||
elif val == 12: # cursor color
|
||||
old, self.cursor.color = self.cursor.color, param
|
||||
if old != self.cursor.color:
|
||||
self.cursor_changed(self.cursor)
|
||||
self.cursor_changed()
|
||||
|
||||
if color_names:
|
||||
for i, cn in enumerate(filter(None, color_names.split(';'))):
|
||||
|
||||
@ -25,46 +25,36 @@ def merge_ranges(ranges: Set[Tuple[int]]) -> Iterator[Tuple[int]]:
|
||||
|
||||
class ChangeTracker:
|
||||
|
||||
def __init__(self, mark_dirtied=lambda: None):
|
||||
def __init__(self):
|
||||
self.reset()
|
||||
self.mark_dirtied = mark_dirtied
|
||||
|
||||
def reset(self):
|
||||
self._dirty = False
|
||||
self.changed_cursor = None
|
||||
self.dirty = False
|
||||
self.changed_cursor = False
|
||||
self.changed_cells = defaultdict(set)
|
||||
self.changed_lines = set()
|
||||
self.screen_changed = False
|
||||
self.history_line_added_count = 0
|
||||
|
||||
def dirty(self):
|
||||
if not self._dirty:
|
||||
self._dirty = True
|
||||
self.mark_dirtied()
|
||||
|
||||
def cursor_changed(self, cursor) -> None:
|
||||
self.changed_cursor = cursor
|
||||
self.dirty()
|
||||
|
||||
def cursor_position_changed(self, cursor) -> None:
|
||||
self.changed_cursor = cursor
|
||||
self.dirty()
|
||||
def cursor_changed(self) -> None:
|
||||
self.changed_cursor = True
|
||||
self.dirty = True
|
||||
|
||||
def update_screen(self):
|
||||
self.screen_changed = True
|
||||
self.dirty()
|
||||
self.dirty = True
|
||||
|
||||
def update_line_range(self, first_line, last_line):
|
||||
self.changed_lines |= set(range(first_line, last_line + 1))
|
||||
self.dirty()
|
||||
self.dirty = True
|
||||
|
||||
def update_cell_range(self, y, first_cell, last_cell):
|
||||
self.changed_cells[y].add((first_cell, last_cell))
|
||||
self.dirty()
|
||||
self.dirty = True
|
||||
|
||||
def line_added_to_history(self):
|
||||
self.history_line_added_count += 1
|
||||
self.dirty()
|
||||
self.dirty = True
|
||||
|
||||
def consolidate_changes(self):
|
||||
if self.screen_changed:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user