Skip to content

Commit

Permalink
Introduce supportedModes bit mask for meters
Browse files Browse the repository at this point in the history
This allows meters to limit the available display modes/styles
based on a bit mask for each meter class. Doing so allows to
disable display modes that make little or no sense for a
specific meter.

Co-authored-by: Benny Baumann <[email protected]>
Co-authored-by: Kang-Che Sung <[email protected]>
  • Loading branch information
Explorer09 and BenBE committed May 22, 2024
1 parent a395186 commit 1723ed7
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 8 deletions.
40 changes: 35 additions & 5 deletions Meter.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ in the source distribution for its full text.
#include "XUtils.h"


#ifndef UINT32_WIDTH
#define UINT32_WIDTH 32
#endif

#define GRAPH_HEIGHT 4 /* Unit: rows (lines) */

typedef struct MeterMode_ {
Expand Down Expand Up @@ -380,7 +384,9 @@ Meter* Meter_new(const Machine* host, unsigned int param, const MeterClass* type
if (Meter_initFn(this)) {
Meter_init(this);
}

Meter_setMode(this, type->defaultMode);
assert(this->mode > 0);
return this;
}

Expand Down Expand Up @@ -439,21 +445,28 @@ void Meter_setCaption(Meter* this, const char* caption) {
}

void Meter_setMode(Meter* this, MeterModeId modeIndex) {
if (modeIndex > 0 && modeIndex == this->mode) {
if (modeIndex == this->mode) {
assert(this->mode > 0);
return;
}

if (modeIndex == 0) {
modeIndex = 1;
uint32_t supportedModes = Meter_supportedModes(this);
if (!supportedModes) {
supportedModes = METERMODE_DEFAULT_SUPPORTED;
}
assert(supportedModes);
assert(!(supportedModes & (1 << 0)));

assert(modeIndex < LAST_METERMODE);
assert(LAST_METERMODE <= UINT32_WIDTH);
if (modeIndex >= LAST_METERMODE || !(supportedModes & (1UL << modeIndex)))
return;

assert(modeIndex >= 1);
if (Meter_updateModeFn(this)) {
assert(Meter_drawFn(this));
this->draw = Meter_drawFn(this);
Meter_updateMode(this, modeIndex);
} else {
assert(modeIndex >= 1);
free(this->drawData.values);
this->drawData.values = NULL;
this->drawData.nValues = 0;
Expand All @@ -465,6 +478,23 @@ void Meter_setMode(Meter* this, MeterModeId modeIndex) {
this->mode = modeIndex;
}

MeterModeId Meter_nextSupportedMode(const Meter* this) {
uint32_t supportedModes = Meter_supportedModes(this);
if (!supportedModes) {
supportedModes = METERMODE_DEFAULT_SUPPORTED;
}
assert(supportedModes);

assert(this->mode < UINT32_WIDTH);
uint32_t modeMask = ((uint32_t)-1 << 1) << this->mode;
uint32_t nextModes = supportedModes & modeMask;
if (!nextModes) {
nextModes = supportedModes;
}

return (MeterModeId)countTrailingZeros(nextModes);
}

ListItem* Meter_toListItem(const Meter* this, bool moving) {
char mode[20];
if (this->mode > 0) {
Expand Down
4 changes: 4 additions & 0 deletions Meter.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ typedef struct MeterClass_ {
const Meter_GetCaption getCaption;
const Meter_GetUiName getUiName;
const MeterModeId defaultMode;
const uint32_t supportedModes; /* bitset of supported modes, 1<<mode_id */
const double total;
const int* const attributes;
const char* const name; /* internal name of the meter, must not contain any space */
Expand All @@ -88,6 +89,7 @@ typedef struct MeterClass_ {
#define Meter_getUiName(this_,n_,l_) As_Meter(this_)->getUiName((const Meter*)(this_),n_,l_)
#define Meter_getCaptionFn(this_) As_Meter(this_)->getCaption
#define Meter_getCaption(this_) (Meter_getCaptionFn(this_) ? As_Meter(this_)->getCaption((const Meter*)(this_)) : (this_)->caption)
#define Meter_supportedModes(this_) As_Meter(this_)->supportedModes
#define Meter_attributes(this_) As_Meter(this_)->attributes
#define Meter_name(this_) As_Meter(this_)->name
#define Meter_uiName(this_) As_Meter(this_)->uiName
Expand Down Expand Up @@ -139,6 +141,8 @@ void Meter_setCaption(Meter* this, const char* caption);

void Meter_setMode(Meter* this, MeterModeId modeIndex);

MeterModeId Meter_nextSupportedMode(const Meter* this);

ListItem* Meter_toListItem(const Meter* this, bool moving);

extern const MeterClass BlankMeter_class;
Expand Down
7 changes: 7 additions & 0 deletions MeterMode.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,11 @@ enum MeterModeId_ {

typedef unsigned int MeterModeId;

#define METERMODE_DEFAULT_SUPPORTED ( \
(1 << BAR_METERMODE) | \
(1 << TEXT_METERMODE) | \
(1 << GRAPH_METERMODE) | \
(1 << LED_METERMODE) | \
0) // Avoids edits when updating

#endif
4 changes: 1 addition & 3 deletions MetersPanel.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,7 @@ static HandlerResult MetersPanel_eventHandler(Panel* super, int ch) {
if (!Vector_size(this->meters))
break;
Meter* meter = (Meter*) Vector_get(this->meters, selected);
MeterModeId mode = meter->mode + 1;
if (mode == LAST_METERMODE)
mode = 1;
MeterModeId mode = Meter_nextSupportedMode(meter);
Meter_setMode(meter, mode);
Panel_set(super, selected, (Object*) Meter_toListItem(meter, this->moving));
result = HANDLED;
Expand Down

0 comments on commit 1723ed7

Please sign in to comment.