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"
9#include "ttx/terminal/row.h"
10
11namespace ttx::terminal {
23class RowGroup {
24public:
25 explicit RowGroup() {
26 // Ensure that multi cell ID 1 is the standard wide cell. This allows for
27 // fast path optimizations.
28 ASSERT_EQ(1, m_multi_cell_info.allocate({ wide_multi_cell_info }));
29 }
30
31 auto rows() -> di::Ring<Row>& { return m_rows; }
32 auto rows() const -> di::Ring<Row> const& { return m_rows; }
33
34 auto empty() const -> bool { return m_rows.empty(); }
35 auto total_rows() const { return m_rows.size(); }
36
37 void drop_graphics_id(u16& id);
38 void drop_hyperlink_id(u16& id);
39 void drop_multi_cell_id(u16& id);
40
41 auto graphics_rendition(u16 id) const -> GraphicsRendition const&;
42 auto hyperlink(u16 id) const -> Hyperlink const&;
43 auto maybe_hyperlink(u16 id) const -> di::Optional<Hyperlink const&>;
44 auto multi_cell_info(u16 id) const -> MultiCellInfo const&;
45
46 auto graphics_id(GraphicsRendition const& rendition) -> di::Optional<u16> {
47 if (rendition == GraphicsRendition {}) {
48 return 0;
49 }
50 return m_graphics_renditions.lookup_key(rendition);
51 }
52 auto use_graphics_id(u16 id) -> u16 {
53 if (!id) {
54 return 0;
55 }
56 return m_graphics_renditions.use_id(id);
57 }
58 auto allocate_graphics_id(GraphicsRendition const& rendition) -> di::Optional<u16> {
59 return m_graphics_renditions.allocate(rendition);
60 }
61 auto maybe_allocate_graphics_id(GraphicsRendition const& rendition) -> di::Optional<u16>;
62
63 auto hyperlink_id(di::String const& hyperlink_id) -> di::Optional<u16> {
64 return m_hyperlinks.lookup_key(hyperlink_id);
65 }
66 auto use_hyperlink_id(u16 id) -> u16 {
67 if (!id) {
68 return 0;
69 }
70 return m_hyperlinks.use_id(id);
71 }
72 auto allocate_hyperlink_id(Hyperlink&& hyperlink) -> di::Optional<u16> {
73 return m_hyperlinks.allocate(di::move(hyperlink));
74 }
75 auto maybe_allocate_hyperlink_id(Hyperlink const& hyperlink) -> di::Optional<u16>;
76
77 auto multi_cell_id(MultiCellInfo const& multi_cell_info) -> di::Optional<u16> {
79 return 0;
80 }
82 return 1;
83 }
84 return m_multi_cell_info.lookup_key(multi_cell_info);
85 }
86 auto use_multi_cell_id(u16 id) -> u16 {
87 if (id <= 1) {
88 return id;
89 }
90 return m_multi_cell_info.use_id(id);
91 }
92 auto allocate_multi_cell_id(MultiCellInfo const& multi_cell_info) -> di::Optional<u16> {
93 return m_multi_cell_info.allocate(multi_cell_info);
94 }
95 auto maybe_allocate_multi_cell_id(MultiCellInfo const& multi_cell_info) -> di::Optional<u16>;
96
97 auto transfer_from(RowGroup& from, usize from_index, usize to_index, usize row_count,
98 di::Optional<u32> desired_cols = {}) -> usize;
99 auto strip_trailing_empty_cells(usize row_index) -> usize;
100
103 void drop_cell(Cell& cell);
104
105 auto iterate_row(u32 row) const {
106 ASSERT_LT(row, total_rows());
107
108 auto const& row_object = rows()[row];
109
110 // Fetch the indirect data fields for every cell in the row (text, graphics, and hyperlink). This uses
111 // cache_last() so that the transform() can can maintain a mutable text offset counter safely, which
112 // ensures fetching the text associated with a cell is O(1). cache_last() also ensures we do the map lookups
113 // only once for each cell.
114 return row_object.cells |
115 di::transform([this, &row_object, text_offset = 0zu, col = 0u](Cell const& cell) mutable {
116 auto text = [&] {
117 if (cell.text_size == 0) {
118 return di::StringView {};
119 }
120
121 auto text_start = row_object.text.iterator_at_offset(text_offset);
122 text_offset += cell.text_size;
123 auto text_end = row_object.text.iterator_at_offset(text_offset);
124 ASSERT(text_start);
125 ASSERT(text_end);
126 return row_object.text.substr(text_start.value(), text_end.value());
127 }();
128
129 return di::make_tuple(
130 col++, di::ref(cell), text, di::ref(graphics_rendition(cell.graphics_rendition_id)),
132 }) |
133 di::cache_last;
134 }
135
136private:
137 di::Ring<Row> m_rows;
138 IdMap<GraphicsRendition> m_graphics_renditions;
139 IdMap<Hyperlink> m_hyperlinks;
140 IdMap<MultiCellInfo> m_multi_cell_info;
141
142 // This empty graphics rendition is used as an optimization so that we can
143 // return by reference in graphics_rendition() when the id == 0.
144 GraphicsRendition m_empty_graphics;
145};
146}
A two-way map between a numberic id and a value.
Definition id_map.h:39
Represents a group of terminal rows.
Definition row_group.h:23
auto multi_cell_id(MultiCellInfo const &multi_cell_info) -> di::Optional< u16 >
Definition row_group.h:77
auto allocate_multi_cell_id(MultiCellInfo const &multi_cell_info) -> di::Optional< u16 >
Definition row_group.h:92
auto use_graphics_id(u16 id) -> u16
Definition row_group.h:52
auto allocate_graphics_id(GraphicsRendition const &rendition) -> di::Optional< u16 >
Definition row_group.h:58
auto hyperlink_id(di::String const &hyperlink_id) -> di::Optional< u16 >
Definition row_group.h:63
auto maybe_allocate_multi_cell_id(MultiCellInfo const &multi_cell_info) -> di::Optional< u16 >
Definition row_group.cpp:23
auto maybe_allocate_hyperlink_id(Hyperlink const &hyperlink) -> di::Optional< u16 >
Definition row_group.cpp:15
auto iterate_row(u32 row) const
Definition row_group.h:105
auto rows() const -> di::Ring< Row > const &
Definition row_group.h:32
auto hyperlink(u16 id) const -> Hyperlink const &
Definition row_group.cpp:73
auto empty() const -> bool
Definition row_group.h:34
auto graphics_rendition(u16 id) const -> GraphicsRendition const &
Definition row_group.cpp:66
void drop_cell(Cell &cell)
Definition row_group.cpp:54
void drop_graphics_id(u16 &id)
Definition row_group.cpp:31
void drop_multi_cell_id(u16 &id)
Definition row_group.cpp:45
auto maybe_allocate_graphics_id(GraphicsRendition const &rendition) -> di::Optional< u16 >
Definition row_group.cpp:7
auto graphics_id(GraphicsRendition const &rendition) -> di::Optional< u16 >
Definition row_group.h:46
auto rows() -> di::Ring< Row > &
Definition row_group.h:31
auto transfer_from(RowGroup &from, usize from_index, usize to_index, usize row_count, di::Optional< u32 > desired_cols={}) -> usize
Definition row_group.cpp:95
auto allocate_hyperlink_id(Hyperlink &&hyperlink) -> di::Optional< u16 >
Definition row_group.h:72
auto multi_cell_info(u16 id) const -> MultiCellInfo const &
Definition row_group.cpp:85
RowGroup()
Definition row_group.h:25
auto use_multi_cell_id(u16 id) -> u16
Definition row_group.h:86
auto strip_trailing_empty_cells(usize row_index) -> usize
Definition row_group.cpp:174
auto maybe_hyperlink(u16 id) const -> di::Optional< Hyperlink const & >
Definition row_group.cpp:78
auto use_hyperlink_id(u16 id) -> u16
Definition row_group.h:66
auto total_rows() const
Definition row_group.h:35
void drop_hyperlink_id(u16 &id)
Definition row_group.cpp:38
Definition capability.h:8
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:8
u16 text_size
The size in bytes of the text in this cell (0 means no text)
Definition cell.h:14
u16 multi_cell_id
0 means none (single cell)
Definition cell.h:13
u16 graphics_rendition_id
0 means default
Definition cell.h:11
u16 hyperlink_id
0 means none
Definition cell.h:12
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