Skip to content

Commit

Permalink
refactor: Change BufferedWiFiWriter and Compressor into nested classe…
Browse files Browse the repository at this point in the history
…s of DrawableCanvas and move method implementation to cpp file

Signed-off-by: Aditya Agarwal <[email protected]>
  • Loading branch information
Aditya-A-garwal committed Mar 25, 2024
1 parent 4640aa3 commit c8251f3
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 102 deletions.
121 changes: 19 additions & 102 deletions lib/gui/include/widgets/drawablecanvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@
#include "WiFiS3.h"
#include "cstring"

class DrawableCanvas : public BasicWidget {

public:

constexpr static unsigned WIDTH = 312;
constexpr static unsigned HEIGHT = 312;

constexpr static uint16_t DRAWABLE_W = WIDTH - 2;
constexpr static uint16_t DRAWABLE_H = HEIGHT - 2;
constexpr static unsigned MAX_INLINE_COMPRESSED_SEGMENTS = 9;

class BufferedWiFiWriter {

friend class DrawableCanvas;
Expand All @@ -23,49 +34,12 @@ friend class DrawableCanvas;

public:

signed connect(WiFiClient *ptr, const char *server_ip, const uint16_t server_port) {
client = ptr;
return client->connect(IPAddress(server_ip), server_port);
}

void write(const uint8_t *bytes, unsigned len) {

unsigned n;

while (len > 0) {

if (used == BUFFER_CAPACITY) {
flush();
}

n = min(len, BUFFER_CAPACITY - used);
for (const uint8_t *ptr = bytes; ptr != &bytes[n]; ++ptr) {
buf[used++] = *ptr;
}
len -= n;
bytes += n;
}
}

void flush() {

unsigned n;

n = client->write(buf, used);
if (n != used) {
flag = false;
}
used = 0;
}

void stop() {
flush();
client->flush();
client->stop();
signed connect(WiFiClient *ptr, const char *server_ip, const uint16_t server_port);
void write(const uint8_t *bytes, unsigned len);
void flush();
void stop();
};

client = nullptr;
}
};

class Compressor {

Expand All @@ -84,67 +58,10 @@ class Compressor {
segment_t *segments;
};

static unsigned compress(canvas_row_t *row, unsigned max_segments, uint8_t *raw_data, unsigned raw_data_len) {

unsigned finished = 0;

for (unsigned l = 0, r; l < raw_data_len; l = r) {
for (r = 1 + l; r <= raw_data_len; ++r) {
if (r == raw_data_len || raw_data[l] != raw_data[r]) {
break;
}
}

if (++finished > max_segments) {
row->pixel_count = l;
row->segment_count = finished - 1;

return l;
}

row->segments[finished - 1].code = raw_data[l];
row->segments[finished - 1].size = r - l;
}

row->pixel_count = raw_data_len;
row->segment_count = finished;

return raw_data_len;
}

static unsigned uncompress(canvas_row_t *row, uint8_t *raw_data, unsigned raw_data_len) {

uint8_t code;
unsigned size;

if (row->segment_count == 0) {
return 0;
}

for (unsigned s = 0, idx = 0; s < row->segment_count; ++s) {

code = row->segments[s].code;
size = row->segments[s].size;

while (size--) {
raw_data[idx++] = code;
}
}

return row->pixel_count;
}
};

class DrawableCanvas : public BasicWidget {

public:

constexpr static unsigned WIDTH = 312;
constexpr static unsigned HEIGHT = 312;
static unsigned compress(canvas_row_t *row, unsigned max_segments, uint8_t *raw_data, unsigned raw_data_len);
static unsigned uncompress(canvas_row_t *row, uint8_t *raw_data, unsigned raw_data_len);
};

constexpr static uint16_t DRAWABLE_W = WIDTH - 2;
constexpr static uint16_t DRAWABLE_H = HEIGHT - 2;
constexpr static unsigned MAX_INLINE_COMPRESSED_SEGMENTS = 9;

protected:

Expand Down
93 changes: 93 additions & 0 deletions lib/gui/src/widgets/drawablecanvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,3 +394,96 @@ void DrawableCanvas::reset_compressed() {
compressed_rows[r].segments[0].size = DRAWABLE_W;
}
}

signed DrawableCanvas::BufferedWiFiWriter::connect(WiFiClient *ptr, const char *server_ip, const uint16_t server_port) {
client = ptr;
return client->connect(IPAddress(server_ip), server_port);
}

void DrawableCanvas::BufferedWiFiWriter::write(const uint8_t *bytes, unsigned len) {

unsigned n;

while (len > 0) {

if (used == BUFFER_CAPACITY) {
flush();
}

n = min(len, BUFFER_CAPACITY - used);
for (const uint8_t *ptr = bytes; ptr != &bytes[n]; ++ptr) {
buf[used++] = *ptr;
}
len -= n;
bytes += n;
}
}

void DrawableCanvas::BufferedWiFiWriter::flush() {

unsigned n;

n = client->write(buf, used);
if (n != used) {
flag = false;
}
used = 0;
}

void DrawableCanvas::BufferedWiFiWriter::stop() {
flush();
client->flush();
client->stop();

client = nullptr;
}

unsigned DrawableCanvas::Compressor::compress(canvas_row_t *row, unsigned max_segments, uint8_t *raw_data, unsigned raw_data_len) {

unsigned finished = 0;

for (unsigned l = 0, r; l < raw_data_len; l = r) {
for (r = 1 + l; r <= raw_data_len; ++r) {
if (r == raw_data_len || raw_data[l] != raw_data[r]) {
break;
}
}

if (++finished > max_segments) {
row->pixel_count = l;
row->segment_count = finished - 1;

return l;
}

row->segments[finished - 1].code = raw_data[l];
row->segments[finished - 1].size = r - l;
}

row->pixel_count = raw_data_len;
row->segment_count = finished;

return raw_data_len;
}

unsigned DrawableCanvas::Compressor::uncompress(canvas_row_t *row, uint8_t *raw_data, unsigned raw_data_len) {

uint8_t code;
unsigned size;

if (row->segment_count == 0) {
return 0;
}

for (unsigned s = 0, idx = 0; s < row->segment_count; ++s) {

code = row->segments[s].code;
size = row->segments[s].size;

while (size--) {
raw_data[idx++] = code;
}
}

return row->pixel_count;
}

0 comments on commit c8251f3

Please sign in to comment.