Skip to content

Commit fa3469f

Browse files
committed
Terminal/FixedAreaBuffer
1 parent 0c2fa5b commit fa3469f

8 files changed

Lines changed: 153 additions & 85 deletions

File tree

modules/Terminal/Area.mpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@ export module CppUtils.Terminal.Area;
33
import std;
44
import CppUtils.Container.Size;
55
export import CppUtils.Terminal.CharAttributes;
6-
export import :AreaBuffer;
6+
export import :DynamicAreaBuffer;
77
export import :Viewport;
88
export import :Widget;
99
export import :WidgetManager;
1010
export import :WritableAreaView;
1111

1212
export namespace CppUtils::Terminal
1313
{
14-
class Area: public Widget, public AreaBuffer
14+
class Area: public Widget, public DynamicAreaBuffer
1515
{
1616
public:
1717
inline Area(const Container::Size2& size, const Viewport& viewport = {{0, 0}, {0, 0}}):
18-
AreaBuffer{size},
18+
DynamicAreaBuffer{size},
1919
m_viewport{viewport}
2020
{}
2121

@@ -41,16 +41,21 @@ export namespace CppUtils::Terminal
4141
return m_viewport;
4242
}
4343

44+
inline auto fill(const CharAttributes& c) noexcept -> void
45+
{
46+
auto view = WritableAreaView{*this, m_viewport};
47+
view.fill(c);
48+
requestFullRender();
49+
}
50+
4451
inline auto fill(char c) noexcept -> void
4552
{
4653
fill(CharAttributes{c});
4754
}
4855

49-
inline auto fill(const CharAttributes& c) noexcept -> void
56+
inline auto clear() noexcept -> void
5057
{
51-
auto view = WritableAreaView{*this, m_viewport};
52-
view.fill(c);
53-
requestFullRender();
58+
fill(' ');
5459
}
5560

5661
inline auto draw([[maybe_unused]] WritableAreaView& view) noexcept -> void override final

modules/Terminal/AreaBuffer.mpp

Lines changed: 3 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
export module CppUtils.Terminal.Area:AreaBuffer;
1+
export module CppUtils.Terminal.AreaBuffer;
22

3-
import std;
43
import CppUtils.Container.Size;
54
import CppUtils.Terminal.CharAttributes;
65

@@ -9,52 +8,7 @@ export namespace CppUtils::Terminal
98
class AreaBuffer
109
{
1110
public:
12-
using Line = std::vector<CharAttributes>;
13-
using Buffer = std::vector<Line>;
14-
15-
inline AreaBuffer(const Container::Size2& size, CharAttributes defaultCharAttributes = {}):
16-
AreaBuffer{size, Buffer{size.height(), Line{size.width(), defaultCharAttributes}}}
17-
{}
18-
19-
inline AreaBuffer(const Container::Size2& size, char defaultChar):
20-
AreaBuffer{size, CharAttributes{defaultChar}}
21-
{}
22-
23-
inline AreaBuffer(const Container::Size2& size, Buffer&& buffer):
24-
m_size{size},
25-
m_buffer{std::move(buffer)}
26-
{}
27-
28-
inline auto setSize(const Container::Size2& size) noexcept -> void
29-
{
30-
m_size = size;
31-
m_buffer = Buffer{m_size.height(), Line{m_size.width()}};
32-
}
33-
34-
[[nodiscard]] inline auto getSize() const noexcept -> const auto&
35-
{
36-
return m_size;
37-
}
38-
39-
[[nodiscard]] inline auto getChar(const Container::Size2& position) const noexcept -> const CharAttributes&
40-
{
41-
return m_buffer[position.y()][position.x()];
42-
}
43-
44-
inline auto setChar(const Container::Size2& position, const CharAttributes& c) noexcept -> void
45-
{
46-
if (position.x() >= m_size.width() or position.y() >= m_size.height())
47-
return;
48-
m_buffer[position.y()][position.x()] = c;
49-
}
50-
51-
auto getBuffer() const noexcept -> const auto&
52-
{
53-
return m_buffer;
54-
}
55-
56-
private:
57-
Container::Size2 m_size;
58-
Buffer m_buffer;
11+
[[nodiscard]] virtual auto getChar(const Container::Size2& position) const noexcept -> const CharAttributes& = 0;
12+
virtual auto setChar(const Container::Size2& position, const CharAttributes& c) noexcept -> void = 0;
5913
};
6014
}

modules/Terminal/Canvas.mpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ export namespace CppUtils::Terminal
199199
private:
200200
bool m_firstPrint = true;
201201
std::atomic_bool m_stopEvent = false;
202-
AreaBuffer m_previousBuffer;
202+
DynamicAreaBuffer m_previousBuffer;
203203
WidgetManager m_widgetManager;
204204
};
205205
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
export module CppUtils.Terminal.Area:DynamicAreaBuffer;
2+
3+
import std;
4+
import CppUtils.Container.Size;
5+
import CppUtils.Terminal.AreaBuffer;
6+
import CppUtils.Terminal.CharAttributes;
7+
8+
export namespace CppUtils::Terminal
9+
{
10+
class DynamicAreaBuffer: public AreaBuffer
11+
{
12+
public:
13+
using Line = std::vector<CharAttributes>;
14+
using Buffer = std::vector<Line>;
15+
16+
inline DynamicAreaBuffer(const Container::Size2& size, CharAttributes defaultCharAttributes = {}):
17+
DynamicAreaBuffer{size, Buffer{size.height(), Line{size.width(), defaultCharAttributes}}}
18+
{}
19+
20+
inline DynamicAreaBuffer(const Container::Size2& size, char defaultChar):
21+
DynamicAreaBuffer{size, CharAttributes{defaultChar}}
22+
{}
23+
24+
inline DynamicAreaBuffer(const Container::Size2& size, Buffer&& buffer):
25+
m_size{size},
26+
m_buffer{std::move(buffer)}
27+
{}
28+
29+
inline auto setSize(const Container::Size2& size) noexcept -> void
30+
{
31+
m_size = size;
32+
m_buffer = Buffer{m_size.height(), Line{m_size.width()}};
33+
}
34+
35+
[[nodiscard]] inline auto getSize() const noexcept -> const auto&
36+
{
37+
return m_size;
38+
}
39+
40+
[[nodiscard]] virtual auto getChar(const Container::Size2& position) const noexcept -> const CharAttributes&
41+
{
42+
return m_buffer[position.y()][position.x()];
43+
}
44+
45+
inline auto setChar(const Container::Size2& position, const CharAttributes& c) noexcept -> void
46+
{
47+
if (position.x() >= m_size.width() or position.y() >= m_size.height())
48+
return;
49+
m_buffer[position.y()][position.x()] = c;
50+
}
51+
52+
[[nodiscard]] inline auto getBuffer() const noexcept -> const auto&
53+
{
54+
return m_buffer;
55+
}
56+
57+
private:
58+
Container::Size2 m_size;
59+
Buffer m_buffer;
60+
};
61+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
export module CppUtils.Terminal.FixedAreaBuffer;
2+
3+
import std;
4+
import CppUtils.Container.Size;
5+
import CppUtils.Terminal.AreaBuffer;
6+
import CppUtils.Terminal.CharAttributes;
7+
8+
export namespace CppUtils::Terminal
9+
{
10+
template<std::size_t Width, std::size_t Height>
11+
class FixedAreaBuffer final: public AreaBuffer
12+
{
13+
public:
14+
using Line = std::array<CharAttributes, Width>;
15+
using Buffer = std::array<Line, Height>;
16+
static constexpr auto size = Container::Size2{Width, Height};
17+
18+
inline constexpr FixedAreaBuffer(CharAttributes defaultCharAttributes = {}):
19+
m_buffer{[](auto v) constexpr -> Buffer {
20+
auto line = Line{};
21+
line.fill(v);
22+
auto buffer = Buffer{};
23+
buffer.fill(line);
24+
return buffer;
25+
}(defaultCharAttributes)}
26+
{}
27+
28+
inline constexpr FixedAreaBuffer(char defaultChar):
29+
FixedAreaBuffer{CharAttributes{defaultChar}}
30+
{}
31+
32+
inline constexpr FixedAreaBuffer(Buffer buffer):
33+
m_buffer{buffer}
34+
{}
35+
36+
[[nodiscard]] virtual constexpr auto getChar(const Container::Size2& position) const noexcept -> const CharAttributes&
37+
{
38+
return m_buffer[position.y()][position.x()];
39+
}
40+
41+
inline constexpr auto setChar(const Container::Size2& position, const CharAttributes& c) noexcept -> void
42+
{
43+
if (position.x() >= size.width() or position.y() >= size.height())
44+
return;
45+
m_buffer[position.y()][position.x()] = c;
46+
}
47+
48+
[[nodiscard]] inline constexpr auto getBuffer() const noexcept -> const auto&
49+
{
50+
return m_buffer;
51+
}
52+
53+
private:
54+
Buffer m_buffer;
55+
};
56+
}

modules/Terminal/Spinner.mpp

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,23 @@ import std;
44
import CppUtils.Terminal.Area;
55
import CppUtils.Container.Size;
66
import CppUtils.Chrono.Concept;
7+
export import CppUtils.Terminal.FixedAreaBuffer;
78

89
export namespace CppUtils::Terminal
910
{
10-
template<Chrono::Duration Duration = std::chrono::milliseconds>
11+
template<std::size_t Width, std::size_t Height, std::size_t NbFrames, Chrono::Duration Duration = std::chrono::milliseconds>
1112
class Spinner final: public Widget
1213
{
1314
public:
14-
inline Spinner(const Container::Size2& size, std::vector<AreaBuffer>&& frames, const Duration& duration = std::chrono::milliseconds{50}):
15-
m_size{size},
16-
m_frames{std::move(frames)},
15+
using Frame = FixedAreaBuffer<Width, Height>;
16+
using Frames = std::array<Frame, NbFrames>;
17+
static constexpr auto size = Frame::size;
18+
19+
inline Spinner(const Frames& frames, const Duration& duration = std::chrono::milliseconds{50}):
20+
m_frames{frames},
1721
m_duration{duration}
1822
{}
1923

20-
inline auto editFrame(std::size_t frame, AreaBuffer&& buffer) noexcept -> void
21-
{
22-
if (frame >= std::size(m_frames))
23-
return;
24-
m_frames[frame] = std::move(buffer);
25-
}
26-
2724
inline auto draw(WritableAreaView& view) noexcept -> void
2825
{
2926
if (std::empty(m_frames))
@@ -35,18 +32,12 @@ export namespace CppUtils::Terminal
3532
requestUpdate(m_duration);
3633
}
3734

38-
[[nodiscard]] inline constexpr auto getSize() const noexcept -> const auto&
39-
{
40-
return m_size;
41-
}
42-
4335
private:
44-
Container::Size2 m_size;
4536
std::size_t m_frame = 0;
46-
std::vector<AreaBuffer> m_frames;
37+
const Frames& m_frames;
4738
Duration m_duration;
4839
};
4940

50-
template<Chrono::Duration Duration>
51-
Spinner(const Container::Size2& size, std::vector<AreaBuffer::Buffer>&& frames, const Duration& duration) -> Spinner<Duration>;
41+
template<std::size_t Width, std::size_t Height, std::size_t NbFrames, Chrono::Duration Duration = std::chrono::milliseconds>
42+
Spinner(std::array<FixedAreaBuffer<Width, Height>, NbFrames>&& frames, const Duration& duration = std::chrono::milliseconds{50}) -> Spinner<Width, Height, NbFrames, Duration>;
5243
}

modules/Terminal/WritableAreaView.mpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
export module CppUtils.Terminal.Area:WritableAreaView;
22

33
import std;
4-
import :AreaBuffer;
4+
import :DynamicAreaBuffer;
55
import :Viewport;
6+
import CppUtils.Terminal.AreaBuffer;
67

78
export namespace CppUtils::Terminal
89
{
910
class WritableAreaView final
1011
{
1112
public:
12-
WritableAreaView(AreaBuffer& areaBuffer, Viewport viewport):
13+
WritableAreaView(DynamicAreaBuffer& areaBuffer, Viewport viewport):
1314
m_areaBuffer{areaBuffer},
1415
m_viewport{std::move(viewport)}
1516
{}

tests/Terminal/Canvas.mpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,12 @@ export namespace CppUtils::UnitTest::Terminal::Canvas
4444

4545
suite.addTest("Spinner", [&] {
4646
auto canvas = CppUtils::Terminal::v2::Canvas{CppUtils::Container::Size2{1, 1}};
47-
auto frames = std::vector<CppUtils::Terminal::AreaBuffer>{
48-
{CppUtils::Container::Size2{1, 1}, '-'},
49-
{CppUtils::Container::Size2{1, 1}, '\\'},
50-
{CppUtils::Container::Size2{1, 1}, '|'},
51-
{CppUtils::Container::Size2{1, 1}, '/'}};
52-
canvas.addWidget(std::make_unique<CppUtils::Terminal::Spinner<>>(CppUtils::Container::Size2{1, 1}, std::move(frames)));
47+
constexpr auto frames = std::array{
48+
CppUtils::Terminal::FixedAreaBuffer<1, 1>{'-'},
49+
CppUtils::Terminal::FixedAreaBuffer<1, 1>{'\\'},
50+
CppUtils::Terminal::FixedAreaBuffer<1, 1>{'|'},
51+
CppUtils::Terminal::FixedAreaBuffer<1, 1>{'/'}};
52+
canvas.addWidget(std::make_unique<CppUtils::Terminal::Spinner<1, 1, 4>>(frames));
5353
auto scheduler = CppUtils::Thread::Scheduler{};
5454
scheduler.schedule([&canvas]() mutable {
5555
canvas.close();

0 commit comments

Comments
 (0)