ttx 0.1.0
Loading...
Searching...
No Matches
row_group.h
Go to the documentation of this file.
1#pragma once
2
3#include "di/container/ring/prelude.h"
4#include "di/container/view/cache_last.h"
10#include "ttx/terminal/row.h"
11
12namespace ttx::terminal {
24class RowGroup {
25public:
26 explicit RowGroup() {
27 // Ensure that multi cell ID 1 is the standard wide cell. This allows for
28 // fast path optimizations.
29 ASSERT_EQ(1, m_multi_cell_info.allocate({ wide_multi_cell_info }));
30 }
31
32 auto rows() -> di::Ring<Row>& { return m_rows; }
33 auto rows() const -> di::Ring<Row> const& { return m_rows; }
34
35 auto empty() const -> bool { return m_rows.empty(); }
36 auto total_rows() const { return m_rows.size(); }
37
43 auto reflow(u64 absolute_row_start, u32 target_width) -> ReflowResult;
44
45 void drop_graphics_id(u16& id);
46 void drop_hyperlink_id(u16& id);
47 void drop_multi_cell_id(u16& id);
48
49 auto graphics_rendition(u16 id) const -> GraphicsRendition const&;
50 auto hyperlink(u16 id) const -> Hyperlink const&;
51 auto maybe_hyperlink(u16 id) const -> di::Optional<Hyperlink const&>;
52 auto multi_cell_info(u16 id) const -> MultiCellInfo const&;
53
54 auto graphics_id(GraphicsRendition const& rendition) -> di::Optional<u16> {
55 if (rendition == GraphicsRendition {}) {
56 return 0;
57 }
58 return m_graphics_renditions.lookup_key(rendition);
59 }
60 auto use_graphics_id(u16 id) -> u16 {
61 if (!id) {
62 return 0;
63 }
64 return m_graphics_renditions.use_id(id);
65 }
66 auto allocate_graphics_id(GraphicsRendition const& rendition) -> di::Optional<u16> {
67 return m_graphics_renditions.allocate(rendition);
68 }
69 auto maybe_allocate_graphics_id(GraphicsRendition const& rendition) -> di::Optional<u16>;
70
71 auto hyperlink_id(di::String const& hyperlink_id) -> di::Optional<u16> {
72 return m_hyperlinks.lookup_key(hyperlink_id);
73 }
74 auto use_hyperlink_id(u16 id) -> u16 {
75 if (!id) {
76 return 0;
77 }
78 return m_hyperlinks.use_id(id);
79 }
80 auto allocate_hyperlink_id(Hyperlink&& hyperlink) -> di::Optional<u16> {
81 return m_hyperlinks.allocate(di::move(hyperlink));
82 }
83 auto maybe_allocate_hyperlink_id(Hyperlink const& hyperlink) -> di::Optional<u16>;
84
85 auto multi_cell_id(MultiCellInfo const& multi_cell_info) -> di::Optional<u16> {
87 return 0;
88 }
90 return 1;
91 }
92 return m_multi_cell_info.lookup_key(multi_cell_info);
93 }
94 auto use_multi_cell_id(u16 id) -> u16 {
95 if (id <= 1) {
96 return id;
97 }
98 return m_multi_cell_info.use_id(id);
99 }
100 auto allocate_multi_cell_id(MultiCellInfo const& multi_cell_info) -> di::Optional<u16> {
101 return m_multi_cell_info.allocate(multi_cell_info);
102 }
103 auto maybe_allocate_multi_cell_id(MultiCellInfo const& multi_cell_info) -> di::Optional<u16>;
104
105 auto transfer_from(RowGroup& from, usize from_index, usize to_index, usize row_count,
106 di::Optional<u32> desired_cols = {}) -> usize;
107 auto strip_trailing_empty_cells(usize row_index) -> usize;
108
111 void drop_cell(Cell& cell);
112
113 auto iterate_row(u32 row) const {
114 ASSERT_LT(row, total_rows());
115
116 auto const& row_object = rows()[row];
117
118 // Fetch the indirect data fields for every cell in the row (text, graphics, and hyperlink). This uses
119 // cache_last() so that the transform() can can maintain a mutable text offset counter safely, which
120 // ensures fetching the text associated with a cell is O(1). cache_last() also ensures we do the map lookups
121 // only once for each cell.
122 return row_object.cells |
123 di::transform([this, &row_object, text_offset = 0zu, col = 0u](Cell const& cell) mutable {
124 auto text = [&] {
125 if (cell.text_size == 0) {
126 return di::StringView {};
127 }
128
129 auto text_start = row_object.text.iterator_at_offset(text_offset);
130 text_offset += cell.text_size;
131 auto text_end = row_object.text.iterator_at_offset(text_offset);
132 ASSERT(text_start);
133 ASSERT(text_end);
134 return row_object.text.substr(text_start.value(), text_end.value());
135 }();
136
137 return di::make_tuple(
138 col++, di::ref(cell), text, di::ref(graphics_rendition(cell.graphics_rendition_id())),
140 }) |
141 di::cache_last;
142 }
143
144private:
145 di::Ring<Row> m_rows;
146 IdMap<GraphicsRendition> m_graphics_renditions;
147 IdMap<Hyperlink> m_hyperlinks;
148 IdMap<MultiCellInfo> m_multi_cell_info;
149
150 // This empty graphics rendition is used as an optimization so that we can
151 // return by reference in graphics_rendition() when the id == 0.
152 GraphicsRendition m_empty_graphics;
153};
154}
A two-way map between a numberic id and a value.
Definition id_map.h:39
Represents the result of reflowing a RowGroup.
Definition reflow_result.h:22
Represents a group of terminal rows.
Definition row_group.h:24
auto multi_cell_id(MultiCellInfo const &multi_cell_info) -> di::Optional< u16 >
Definition row_group.h:85
auto allocate_multi_cell_id(MultiCellInfo const &multi_cell_info) -> di::Optional< u16 >
Definition row_group.h:100
auto use_graphics_id(u16 id) -> u16
Definition row_group.h:60
auto allocate_graphics_id(GraphicsRendition const &rendition) -> di::Optional< u16 >
Definition row_group.h:66
auto hyperlink_id(di::String const &hyperlink_id) -> di::Optional< u16 >
Definition row_group.h:71
auto maybe_allocate_multi_cell_id(MultiCellInfo const &multi_cell_info) -> di::Optional< u16 >
Definition row_group.cpp:132
auto maybe_allocate_hyperlink_id(Hyperlink const &hyperlink) -> di::Optional< u16 >
Definition row_group.cpp:124
auto iterate_row(u32 row) const
Definition row_group.h:113
auto rows() const -> di::Ring< Row > const &
Definition row_group.h:33
auto hyperlink(u16 id) const -> Hyperlink const &
Definition row_group.cpp:187
auto empty() const -> bool
Definition row_group.h:35
auto graphics_rendition(u16 id) const -> GraphicsRendition const &
Definition row_group.cpp:180
void drop_cell(Cell &cell)
Definition row_group.cpp:163
void drop_graphics_id(u16 &id)
Definition row_group.cpp:140
void drop_multi_cell_id(u16 &id)
Definition row_group.cpp:154
auto maybe_allocate_graphics_id(GraphicsRendition const &rendition) -> di::Optional< u16 >
Definition row_group.cpp:116
auto reflow(u64 absolute_row_start, u32 target_width) -> ReflowResult
Adjust each row in the group according to the new target width.
Definition row_group.cpp:9
auto graphics_id(GraphicsRendition const &rendition) -> di::Optional< u16 >
Definition row_group.h:54
auto rows() -> di::Ring< Row > &
Definition row_group.h:32
auto transfer_from(RowGroup &from, usize from_index, usize to_index, usize row_count, di::Optional< u32 > desired_cols={}) -> usize
Definition row_group.cpp:209
auto allocate_hyperlink_id(Hyperlink &&hyperlink) -> di::Optional< u16 >
Definition row_group.h:80
auto multi_cell_info(u16 id) const -> MultiCellInfo const &
Definition row_group.cpp:199
RowGroup()
Definition row_group.h:26
auto use_multi_cell_id(u16 id) -> u16
Definition row_group.h:94
auto strip_trailing_empty_cells(usize row_index) -> usize
Definition row_group.cpp:290
auto maybe_hyperlink(u16 id) const -> di::Optional< Hyperlink const & >
Definition row_group.cpp:192
auto use_hyperlink_id(u16 id) -> u16
Definition row_group.h:74
auto total_rows() const
Definition row_group.h:36
void drop_hyperlink_id(u16 &id)
Definition row_group.cpp:147
Definition absolute_position.h:6
constexpr auto wide_multi_cell_info
Definition multi_cell_info.h:34
constexpr auto narrow_multi_cell_info
Definition multi_cell_info.h:32
Definition graphics_rendition.h:114
Represents a on-screen terminal cell.
Definition cell.h:9
u16 text_size
The size in bytes of the text in this cell (0 means no text)
Definition cell.h:22
u16 multi_cell_id
0 means none (single cell)
Definition cell.h:21
auto graphics_rendition_id() const -> u16
Definition cell.h:34
auto hyperlink_id() const -> u16
Definition cell.h:35
Shared information for cells linked via text sizing protocol (OSC 66) or double width characters.
Definition multi_cell_info.h:8
Represents a on-screen terminal row of cells.
Definition row.h:9