Added the ability to specify the render buffer size in the constructor.#212
Added the ability to specify the render buffer size in the constructor.#212meetanthony wants to merge 2 commits into
Conversation
…ize can cause an out of memory exception.
|
Hi, Anton! Thank you for proposing a solution. There's no doubt that there are things which simply cannot be done if a capacity is not specified when constructing a So, could you please explain under which circumstances you are using Cheers. |
|
Hello, magiblot. #pragma once
#include <tvision/tv.h>
enum class SpecialSymbols : char8_t {
boxv = 179, // │
boxh = 196, // ─
boxdl = 191, // ┐
boxul = 217, // ┘
boxdr = 218, // ┌
boxur = 192, // └
boxhd = 194, // ┬
boxhu = 193, // ┴
boxvl = 180, // ┤
boxvr = 195, // ├
boxvL = 181, // ╡
boxvR = 198, // ╞
boxhU = 208, // ╨
boxhD = 210, // ╥
boxV = 186, // ║
boxH = 205, // ═
boxDR = 201, // ╔
boxUR = 200, // ╚
boxDL = 187, // ╗
boxUL = 188, // ╝
boxVl = 182, // ╢
boxVL = 185, // ╣
boxVr = 199, // ╟
boxHU = 202, // ╩
boxHD = 203, // ╦
boxVR = 204, // ╠
boxHu = 207, // ╧
boxHd = 209, // ╤
};
class DrawBuffer {
public:
const int width;
const int height;
TColorAttr color = {
TColorRGB{255, 0, 0}, // toxic red
TColorRGB{0, 0, 255} // toxic blue
};
TDrawBuffer b;
DrawBuffer(const int width, const int height)
: width(width), height(height), b(width * height) {
}
void setColor(const TColorAttr color) {
this->color = color;
}
void draw(const char symbol, const int x, const int y, const int count = 1) {
b.moveChar(y * width + x, symbol, color, count);
}
void draw(const SpecialSymbols symbol, const int x, const int y, const int count = 1) {
char c = static_cast<char>(symbol);
b.moveChar(y * width + x, c, color, count);
}
void draw(const std::string &string, const int x, const int y, int maxWidth = -1) {
if (maxWidth == -1)
maxWidth = string.length();
b.moveStr(y * width + x, string, color, maxWidth);
}
const TDrawBuffer &getBuffer() {
return b;
}
};
Thank you again for your work. |
|
Hi, @meetanthony! I suspect that It's not just you, I too have many times resorted to using a multi-line buffer for drawing. However, for this purpose, I think that it's more practical to allocate a large array of screen cells and draw on it manually. That is to say: instead of relying on For example (requires class DrawBuffer {
public:
const int width;
const int height;
TColorAttr color = {
TColorRGB{255, 0, 0}, // toxic red
TColorRGB{0, 0, 255} // toxic blue
};
std::vector<TScreenCell> b;
DrawBuffer(const int width, const int height)
: width(width), height(height), b(width * height) {
}
void setColor(const TColorAttr color) {
this->color = color;
}
void draw(const char symbol, const int x, const int y, const int count = 1) {
auto cells = getRow(y).subspan(x, count);
TText::drawChar(cells, symbol, color);
}
void draw(const SpecialSymbols symbol, const int x, const int y, const int count = 1) {
char c = static_cast<char>(symbol);
draw(c, x, y, count);
}
void draw(const std::string &string, const int x, const int y, int maxWidth = -1) {
if (maxWidth == -1)
maxWidth = strwidth(string); // Use strwidth() for multibyte character support.
auto cells = getRow(y).subspan(x, maxWidth);
TText::drawStr(cells, string, color);
}
const TScreenCell* getBuffer() {
return b.data();
}
private:
TSpan<TScreenCell> getRow(const int y) {
TSpan<TScreenCell> data(b.data(), b.size());
// Using subspan() is safe: it ensures the returned span is within bounds.
return data.subspan(y * width, width);
}
};Cheers. |
|
Thanks for the sample code provided - I checked it and everything works as intended. Well, if you don't think it's worth making these changes to the base code, then I should close the pool request. It's a pity, of course, that someone might encounter this again. It may be worth adding the code with the rendering of the entire control at a time to the examples (although I might have missed something when I examined them). |
Added the ability to specify the render buffer size in the constructor. This can be used to render the entire control to the buffer and then call the
writeBufmethod once, instead of multiplewriteLinecalls.Backward compatibility is preserved by using the default value (-1).