From 4eb277f19e2c2b821552319ab7b222a4a630a8ac Mon Sep 17 00:00:00 2001 From: Neil McKechnie Date: Wed, 22 Feb 2023 21:06:03 +0000 Subject: [PATCH] Refactor Display handler to (hopefully) improve clarity. --- Display.cpp | 107 +++++++++++++++++++++++++++------------------------- Display.h | 14 +++---- 2 files changed, 63 insertions(+), 58 deletions(-) diff --git a/Display.cpp b/Display.cpp index 587a107..2c44778 100644 --- a/Display.cpp +++ b/Display.cpp @@ -36,7 +36,7 @@ * not held up significantly. The exception to this is when * the loop2() function is called with force=true, where * a screen update is executed to completion. This is normally - * only done during start-up. + * only noMoreRowsToDisplay during start-up. * The scroll mode is selected by defining SCROLLMODE as 0, 1 or 2 * in the config.h. * #define SCROLLMODE 0 is scroll continuous (fill screen if poss), @@ -53,9 +53,9 @@ Display::Display(DisplayDevice *deviceDriver) { // Get device dimensions in characters (e.g. 16x2). numCharacterColumns = _deviceDriver->getNumCols(); numCharacterRows = _deviceDriver->getNumRows();; - for (uint8_t row=0; rowclearNative(); for (uint8_t row = 0; row < MAX_CHARACTER_ROWS; row++) rowBuffer[row][0] = '\0'; - topRow = -1; // loop2 will fill from row 0 + topRow = ROW_INITIAL; // loop2 will fill from row 0 } void Display::_setRow(uint8_t line) { hotRow = line; hotCol = 0; - rowBuffer[hotRow][hotCol] = 0; // Clear existing text + rowBuffer[hotRow][0] = 0; // Clear existing text } size_t Display::_write(uint8_t b) { @@ -109,63 +109,57 @@ Display *Display::loop2(bool force) { return NULL; } else { // force full screen update from the beginning. - rowFirst = -1; - rowNext = 0; + rowFirst = ROW_INITIAL; + rowNext = ROW_INITIAL; bufferPointer = 0; - done = false; + noMoreRowsToDisplay = false; slot = 0; } do { if (bufferPointer == 0) { // Find a line of data to write to the screen. - if (rowFirst < 0) rowFirst = rowNext; - skipBlankRows(); - if (!done) { - // Non-blank line found, so copy it. - for (uint8_t i = 0; i < sizeof(buffer); i++) + if (rowFirst == ROW_INITIAL) rowFirst = rowNext; + if (findNextNonBlankRow()) { + // Non-blank line found, so copy it (including terminator) + for (uint8_t i = 0; i <= MAX_CHARACTER_COLS; i++) buffer[i] = rowBuffer[rowNext][i]; - } else - buffer[0] = '\0'; // Empty line + } else { + // No non-blank lines left, so draw a blank line + buffer[0] = 0; + } _deviceDriver->setRowNative(slot); // Set position for display charIndex = 0; bufferPointer = &buffer[0]; - } else { - // Write next character, or a space to erase current position. char ch = *bufferPointer; if (ch) { _deviceDriver->writeNative(ch); bufferPointer++; - } else + } else { _deviceDriver->writeNative(' '); + } if (++charIndex >= MAX_CHARACTER_COLS) { // Screen slot completed, move to next slot on screen - slot++; bufferPointer = 0; - if (!done) { - moveToNextRow(); - skipBlankRows(); - } - } - - if (slot >= numCharacterRows) { - // Last slot finished, reset ready for next screen update. + slot++; + if (slot >= numCharacterRows) { + // Last slot on screen written, reset ready for next screen update. #if SCROLLMODE==2 - if (!done) { - // On next refresh, restart one row on from previous start. - rowNext = rowFirst; - moveToNextRow(); - skipBlankRows(); - } + if (!noMoreRowsToDisplay) { + // On next refresh, restart one row on from previous start. + rowNext = rowFirst; + findNextNonBlankRow(); + } #endif - done = false; - slot = 0; - rowFirst = -1; - lastScrollTime = currentMillis; - return NULL; + noMoreRowsToDisplay = false; + slot = 0; + rowFirst = ROW_INITIAL; + lastScrollTime = currentMillis; + return NULL; + } } } } while (force); @@ -173,19 +167,30 @@ Display *Display::loop2(bool force) { return NULL; } -void Display::moveToNextRow() { - rowNext = rowNext + 1; - if (rowNext >= MAX_CHARACTER_ROWS) rowNext = 0; +bool Display::findNextNonBlankRow() { + while (!noMoreRowsToDisplay) { + if (rowNext == ROW_INITIAL) + rowNext = 0; + else + rowNext = rowNext + 1; + if (rowNext >= MAX_CHARACTER_ROWS) rowNext = ROW_INITIAL; #if SCROLLMODE == 1 - // Finished if we've looped back to row 0 - if (rowNext == 0) done = true; + // Finished if we've looped back to start + if (rowNext == ROW_INITIAL) { + noMoreRowsToDisplay = true; + return false; + } #else - // Finished if we're back to the first one shown - if (rowNext == rowFirst) done = true; + // Finished if we're back to the first one shown + if (rowNext == rowFirst) { + noMoreRowsToDisplay = true; + return false; + } #endif -} - -void Display::skipBlankRows() { - while (!done && rowBuffer[rowNext][0] == 0) - moveToNextRow(); + if (rowBuffer[rowNext][0] != 0) { + // Found non-blank row + return true; + } + } + return false; } \ No newline at end of file diff --git a/Display.h b/Display.h index d747680..be2479d 100644 --- a/Display.h +++ b/Display.h @@ -40,6 +40,7 @@ public: static const int MAX_CHARACTER_ROWS = 8; static const int MAX_CHARACTER_COLS = MAX_MSG_SIZE; static const long DISPLAY_SCROLL_TIME = 3000; // 3 seconds + static const uint8_t ROW_INITIAL = 255; private: DisplayDevice *_deviceDriver; @@ -47,18 +48,18 @@ private: unsigned long lastScrollTime = 0; uint8_t hotRow = 0; uint8_t hotCol = 0; - int8_t topRow = 0; + uint8_t topRow = 0; uint8_t slot = 0; - int8_t rowFirst = -1; - int8_t rowNext = 0; + uint8_t rowFirst = ROW_INITIAL; + uint8_t rowNext = ROW_INITIAL; uint8_t charIndex = 0; char buffer[MAX_CHARACTER_COLS + 1]; char* bufferPointer = 0; - bool done = false; + bool noMoreRowsToDisplay = false; uint16_t numCharacterRows; uint16_t numCharacterColumns = MAX_CHARACTER_COLS; - char *rowBuffer[MAX_CHARACTER_ROWS]; + char rowBuffer[MAX_CHARACTER_ROWS][MAX_CHARACTER_COLS+1]; public: void begin() override; @@ -68,8 +69,7 @@ public: void _refresh() override; void _displayLoop() override; Display *loop2(bool force); - void moveToNextRow(); - void skipBlankRows(); + bool findNextNonBlankRow(); };