Skip to content

Mirrored Input/Output Graph Mode #1701

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions DiskIOMeter.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ static void DiskIOMeter_updateValues(Meter* this) {
} else {
diff = 0;
}
this->values[1] = diff;
Meter_humanUnit(cached_read_diff_str, diff, sizeof(cached_read_diff_str));

if (data.totalBytesWritten > cached_write_total) {
Expand All @@ -81,6 +82,7 @@ static void DiskIOMeter_updateValues(Meter* this) {
} else {
diff = 0;
}
this->values[2] = diff;
Meter_humanUnit(cached_write_diff_str, diff, sizeof(cached_write_diff_str));

cached_utilisation_diff = 0.0;
Expand Down Expand Up @@ -156,8 +158,13 @@ const MeterClass DiskIOMeter_class = {
},
.updateValues = DiskIOMeter_updateValues,
.defaultMode = TEXT_METERMODE,
.supportedModes = METERMODE_DEFAULT_SUPPORTED,
.maxItems = 1,
.supportedModes =
(1 << BAR_METERMODE) |
(1 << TEXT_METERMODE) |
(1 << GRAPH_METERMODE) |
(1 << LED_METERMODE) |
(1 << BIPOLAR_METERMODE),
.maxItems = 3,
.total = 1.0,
.attributes = DiskIOMeter_attributes,
.name = "DiskIO",
Expand Down
121 changes: 94 additions & 27 deletions Meter.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,40 +185,53 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) {
#ifdef HAVE_LIBNCURSESW

#define PIXPERROW_UTF8 4
static const char* const GraphMeterMode_dotsUtf8[] = {
static const char* const GraphMeterMode_top_dotsUtf8[] = {
/*00*/" ", /*01*/"⢀", /*02*/"⢠", /*03*/"⢰", /*04*/ "⢸",
/*10*/"⡀", /*11*/"⣀", /*12*/"⣠", /*13*/"⣰", /*14*/ "⣸",
/*20*/"⡄", /*21*/"⣄", /*22*/"⣤", /*23*/"⣴", /*24*/ "⣼",
/*30*/"⡆", /*31*/"⣆", /*32*/"⣦", /*33*/"⣶", /*34*/ "⣾",
/*40*/"⡇", /*41*/"⣇", /*42*/"⣧", /*43*/"⣷", /*44*/ "⣿"
};

static const char* const GraphMeterMode_bottom_dotsUtf8[] = {
/*00*/" ", /*01*/"⠈", /*02*/"⠘", /*03*/"⠸", /*04*/ "⢸",
/*10*/"⠁", /*11*/"⠉", /*12*/"⠙", /*13*/"⠹", /*14*/ "⢹",
/*20*/"⠃", /*21*/"⠋", /*22*/"⠛", /*23*/"⠻", /*24*/ "⢻",
/*30*/"⠇", /*31*/"⠏", /*32*/"⠟", /*33*/"⠿", /*34*/ "⢿",
/*40*/"⡇", /*41*/"⡏", /*42*/"⡟", /*43*/"⡿", /*44*/ "⣿"
};

static const char* const* const GraphMeterMode_dotsUtf8[2] = {
GraphMeterMode_top_dotsUtf8,
GraphMeterMode_bottom_dotsUtf8
};
#endif

#define PIXPERROW_ASCII 2
static const char* const GraphMeterMode_dotsAscii[] = {
static const char* const GraphMeterMode_top_dotsAscii[] = {
/*00*/" ", /*01*/".", /*02*/":",
/*10*/".", /*11*/".", /*12*/":",
/*20*/":", /*21*/":", /*22*/":"
};

static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
assert(x >= 0);
assert(w <= INT_MAX - x);
static const char* const GraphMeterMode_bottom_dotsAscii[] = {
/*00*/" ", /*01*/"'", /*02*/":",
/*10*/"'", /*11*/"'", /*12*/":",
/*20*/":", /*21*/":", /*22*/":"
};

// Draw the caption
const int captionLen = 3;
const char* caption = Meter_getCaption(this);
if (w >= captionLen) {
attrset(CRT_colors[METER_TEXT]);
mvaddnstr(y, x, caption, captionLen);
}
w -= captionLen;
static const char* const* const GraphMeterMode_dotsAscii[2] = {
GraphMeterMode_top_dotsAscii,
GraphMeterMode_bottom_dotsAscii
};

assert(this->h >= 1);
int h = this->h;
static void GraphMeterMode_drawGraph(Meter* this, int x, int y, int w, int h, int channel) {
assert(x >= 0);
assert(y >= 0);
assert(w > 0 && w <= INT_MAX - x);
assert(h > 0 && h <= INT_MAX - y);

GraphData* data = &this->drawData;
GraphData* data = &this->drawData[channel+1];

// Expand the graph data buffer if necessary
assert(data->nValues / 2 <= INT_MAX);
Expand Down Expand Up @@ -247,28 +260,35 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
data->values[nValues - 1] = 0.0;
if (this->curItems > 0) {
assert(this->values);
data->values[nValues - 1] = sumPositiveValues(this->values, this->curItems);
if (channel < 0) {
data->values[nValues - 1] = sumPositiveValues(this->values, this->curItems);
} else {
assert(this->curItems > channel);
data->values[nValues - 1] = this->values[channel];
}
}
}

if (w < 1) {
goto end;
}
x += captionLen;

// Graph drawing style (character set, etc.)
const char* const* GraphMeterMode_dots;
int GraphMeterMode_pixPerRow;
const char* const* GraphMeterMode_dots = NULL;
int GraphMeterMode_pixPerRow = 0;
int GraphMeterMode_dotSet = channel >= 0 ? channel : 0;
#ifdef HAVE_LIBNCURSESW
if (CRT_utf8) {
GraphMeterMode_dots = GraphMeterMode_dotsUtf8;
GraphMeterMode_dots = GraphMeterMode_dotsUtf8[GraphMeterMode_dotSet];
GraphMeterMode_pixPerRow = PIXPERROW_UTF8;
} else
#endif
{
GraphMeterMode_dots = GraphMeterMode_dotsAscii;
GraphMeterMode_dots = GraphMeterMode_dotsAscii[GraphMeterMode_dotSet];
GraphMeterMode_pixPerRow = PIXPERROW_ASCII;
}
assert(GraphMeterMode_dots);
assert(GraphMeterMode_pixPerRow > 0);

// Starting positions of graph data and terminal column
if ((size_t)w > nValues / 2) {
Expand All @@ -290,7 +310,8 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
int line2 = CLAMP(v2 - (GraphMeterMode_pixPerRow * (h - 1 - line)), 0, GraphMeterMode_pixPerRow);

attrset(CRT_colors[colorIdx]);
mvaddstr(y + line, x + col, GraphMeterMode_dots[line1 * (GraphMeterMode_pixPerRow + 1) + line2]);
int screen_row = GraphMeterMode_dotSet == 0 ? y + line : y + h - line - 1;
mvaddstr(screen_row, x + col, GraphMeterMode_dots[line1 * (GraphMeterMode_pixPerRow + 1) + line2]);
colorIdx = GRAPH_2;
}
}
Expand All @@ -299,6 +320,44 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
attrset(CRT_colors[RESET_COLOR]);
}

static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
assert(x >= 0);
assert(w <= INT_MAX - x);

// Draw the caption
const int captionLen = 3;
const char* caption = Meter_getCaption(this);
if (w >= captionLen) {
attrset(CRT_colors[METER_TEXT]);
mvaddnstr(y, x, caption, captionLen);
}
w -= captionLen;

// Draw the graph
GraphMeterMode_drawGraph(this, x + captionLen, y, w, this->h, -1);
}

static void BipolarMeterMode_draw(Meter* this, int x, int y, int w) {
assert(x >= 0);
assert(w <= INT_MAX - x);

// Draw the caption
const int captionLen = 3;
const char* caption = Meter_getCaption(this);
if (w >= captionLen) {
attrset(CRT_colors[METER_TEXT]);
mvaddnstr(y, x, caption, captionLen);
}
w -= captionLen;

// Draw the top graph, half height
GraphMeterMode_drawGraph(this, x + captionLen, y, w, this->h / 2, 0);

// Draw the bottom graph, half height
y += this->h / 2;
GraphMeterMode_drawGraph(this, x + captionLen, y, w, this->h / 2, 1);
}

/* ---------- LEDMeterMode ---------- */

static const char* const LEDMeterMode_digitsAscii[] = {
Expand Down Expand Up @@ -404,6 +463,11 @@ static const MeterMode Meter_modes[] = {
.h = DEFAULT_GRAPH_HEIGHT,
.draw = GraphMeterMode_draw,
},
[BIPOLAR_METERMODE] = {
.uiName = "Bipolar",
.h = DEFAULT_GRAPH_HEIGHT,
.draw = BipolarMeterMode_draw,
},
[LED_METERMODE] = {
.uiName = "LED",
.h = 3,
Expand Down Expand Up @@ -483,7 +547,9 @@ void Meter_delete(Object* cast) {
if (Meter_doneFn(this)) {
Meter_done(this);
}
free(this->drawData.values);
for (size_t i = 0; i < ARRAYSIZE(this->drawData); i++) {
free(this->drawData[i].values);
}
free(this->caption);
free(this->values);
free(this);
Expand Down Expand Up @@ -513,9 +579,10 @@ void Meter_setMode(Meter* this, MeterModeId modeIndex) {
this->draw = Meter_drawFn(this);
Meter_updateMode(this, modeIndex);
} else {
free(this->drawData.values);
this->drawData.values = NULL;
this->drawData.nValues = 0;
for (size_t i = 0; i < ARRAYSIZE(this->drawData); i++) {
free(this->drawData[i].values);
this->drawData[i] = (GraphData) { .values = NULL };
}

const MeterMode* mode = &Meter_modes[modeIndex];
this->draw = mode->draw;
Expand Down
2 changes: 1 addition & 1 deletion Meter.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ struct Meter_ {
char* caption;
MeterModeId mode;
unsigned int param;
GraphData drawData;
GraphData drawData[3];
int h;
int columnWidthCount; /**< only used internally by the Header */
uint8_t curItems;
Expand Down
1 change: 1 addition & 0 deletions MeterMode.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ enum MeterModeId_ {
BAR_METERMODE = 1,
TEXT_METERMODE,
GRAPH_METERMODE,
BIPOLAR_METERMODE,
LED_METERMODE,
LAST_METERMODE
};
Expand Down
14 changes: 10 additions & 4 deletions NetworkIOMeter.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,9 @@ static void NetworkIOMeter_updateValues(Meter* this) {
cached_txp_total = data.packetsTransmitted;
}

this->values[0] = cached_rxb_diff;
this->values[1] = cached_txb_diff;
this->values[0] = cached_rxb_diff + cached_txb_diff;
this->values[1] = cached_rxb_diff;
this->values[2] = cached_txb_diff;
if (cached_rxb_diff + cached_txb_diff > this->total) {
this->total = cached_rxb_diff + cached_txb_diff;
}
Expand Down Expand Up @@ -169,8 +170,13 @@ const MeterClass NetworkIOMeter_class = {
},
.updateValues = NetworkIOMeter_updateValues,
.defaultMode = TEXT_METERMODE,
.supportedModes = METERMODE_DEFAULT_SUPPORTED,
.maxItems = 2,
.supportedModes =
(1 << BAR_METERMODE) |
(1 << TEXT_METERMODE) |
(1 << GRAPH_METERMODE) |
(1 << LED_METERMODE) |
(1 << BIPOLAR_METERMODE),
.maxItems = 3,
.total = 100.0,
.attributes = NetworkIOMeter_attributes,
.name = "NetworkIO",
Expand Down
Loading