Skip to content

Commit 1723ed7

Browse files
Explorer09BenBE
andcommitted
Introduce supportedModes bit mask for meters
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 <BenBE@geshi.org> Co-authored-by: Kang-Che Sung <explorer09@gmail.com>
1 parent a395186 commit 1723ed7

File tree

4 files changed

+47
-8
lines changed

4 files changed

+47
-8
lines changed

Meter.c

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ in the source distribution for its full text.
2424
#include "XUtils.h"
2525

2626

27+
#ifndef UINT32_WIDTH
28+
#define UINT32_WIDTH 32
29+
#endif
30+
2731
#define GRAPH_HEIGHT 4 /* Unit: rows (lines) */
2832

2933
typedef struct MeterMode_ {
@@ -380,7 +384,9 @@ Meter* Meter_new(const Machine* host, unsigned int param, const MeterClass* type
380384
if (Meter_initFn(this)) {
381385
Meter_init(this);
382386
}
387+
383388
Meter_setMode(this, type->defaultMode);
389+
assert(this->mode > 0);
384390
return this;
385391
}
386392

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

441447
void Meter_setMode(Meter* this, MeterModeId modeIndex) {
442-
if (modeIndex > 0 && modeIndex == this->mode) {
448+
if (modeIndex == this->mode) {
449+
assert(this->mode > 0);
443450
return;
444451
}
445452

446-
if (modeIndex == 0) {
447-
modeIndex = 1;
453+
uint32_t supportedModes = Meter_supportedModes(this);
454+
if (!supportedModes) {
455+
supportedModes = METERMODE_DEFAULT_SUPPORTED;
448456
}
457+
assert(supportedModes);
458+
assert(!(supportedModes & (1 << 0)));
449459

450-
assert(modeIndex < LAST_METERMODE);
460+
assert(LAST_METERMODE <= UINT32_WIDTH);
461+
if (modeIndex >= LAST_METERMODE || !(supportedModes & (1UL << modeIndex)))
462+
return;
463+
464+
assert(modeIndex >= 1);
451465
if (Meter_updateModeFn(this)) {
452466
assert(Meter_drawFn(this));
453467
this->draw = Meter_drawFn(this);
454468
Meter_updateMode(this, modeIndex);
455469
} else {
456-
assert(modeIndex >= 1);
457470
free(this->drawData.values);
458471
this->drawData.values = NULL;
459472
this->drawData.nValues = 0;
@@ -465,6 +478,23 @@ void Meter_setMode(Meter* this, MeterModeId modeIndex) {
465478
this->mode = modeIndex;
466479
}
467480

481+
MeterModeId Meter_nextSupportedMode(const Meter* this) {
482+
uint32_t supportedModes = Meter_supportedModes(this);
483+
if (!supportedModes) {
484+
supportedModes = METERMODE_DEFAULT_SUPPORTED;
485+
}
486+
assert(supportedModes);
487+
488+
assert(this->mode < UINT32_WIDTH);
489+
uint32_t modeMask = ((uint32_t)-1 << 1) << this->mode;
490+
uint32_t nextModes = supportedModes & modeMask;
491+
if (!nextModes) {
492+
nextModes = supportedModes;
493+
}
494+
495+
return (MeterModeId)countTrailingZeros(nextModes);
496+
}
497+
468498
ListItem* Meter_toListItem(const Meter* this, bool moving) {
469499
char mode[20];
470500
if (this->mode > 0) {

Meter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ typedef struct MeterClass_ {
6565
const Meter_GetCaption getCaption;
6666
const Meter_GetUiName getUiName;
6767
const MeterModeId defaultMode;
68+
const uint32_t supportedModes; /* bitset of supported modes, 1<<mode_id */
6869
const double total;
6970
const int* const attributes;
7071
const char* const name; /* internal name of the meter, must not contain any space */
@@ -88,6 +89,7 @@ typedef struct MeterClass_ {
8889
#define Meter_getUiName(this_,n_,l_) As_Meter(this_)->getUiName((const Meter*)(this_),n_,l_)
8990
#define Meter_getCaptionFn(this_) As_Meter(this_)->getCaption
9091
#define Meter_getCaption(this_) (Meter_getCaptionFn(this_) ? As_Meter(this_)->getCaption((const Meter*)(this_)) : (this_)->caption)
92+
#define Meter_supportedModes(this_) As_Meter(this_)->supportedModes
9193
#define Meter_attributes(this_) As_Meter(this_)->attributes
9294
#define Meter_name(this_) As_Meter(this_)->name
9395
#define Meter_uiName(this_) As_Meter(this_)->uiName
@@ -139,6 +141,8 @@ void Meter_setCaption(Meter* this, const char* caption);
139141

140142
void Meter_setMode(Meter* this, MeterModeId modeIndex);
141143

144+
MeterModeId Meter_nextSupportedMode(const Meter* this);
145+
142146
ListItem* Meter_toListItem(const Meter* this, bool moving);
143147

144148
extern const MeterClass BlankMeter_class;

MeterMode.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,11 @@ enum MeterModeId_ {
1919

2020
typedef unsigned int MeterModeId;
2121

22+
#define METERMODE_DEFAULT_SUPPORTED ( \
23+
(1 << BAR_METERMODE) | \
24+
(1 << TEXT_METERMODE) | \
25+
(1 << GRAPH_METERMODE) | \
26+
(1 << LED_METERMODE) | \
27+
0) // Avoids edits when updating
28+
2229
#endif

MetersPanel.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,7 @@ static HandlerResult MetersPanel_eventHandler(Panel* super, int ch) {
108108
if (!Vector_size(this->meters))
109109
break;
110110
Meter* meter = (Meter*) Vector_get(this->meters, selected);
111-
MeterModeId mode = meter->mode + 1;
112-
if (mode == LAST_METERMODE)
113-
mode = 1;
111+
MeterModeId mode = Meter_nextSupportedMode(meter);
114112
Meter_setMode(meter, mode);
115113
Panel_set(super, selected, (Object*) Meter_toListItem(meter, this->moving));
116114
result = HANDLED;

0 commit comments

Comments
 (0)