Updated the ScreenManager class and added the previousDisplay methods allong with screen refresh rate
This commit is contained in:
parent
6dfee719a9
commit
424a135151
@ -1,6 +1,8 @@
|
||||
#include "ScreenManager.h"
|
||||
|
||||
ScreenManager::ScreenManager(Adafruit_SSD1306 &display, SDCardManager *sdCardManager) : _displayRef(display), _displayColorInverted(false), _displayDimmed(false), _enabled(true), _currentView(NO_CURRENT_VIEW), _error(OK)
|
||||
ScreenManager::ScreenManager(Adafruit_SSD1306 &display, SDCardManager *sdCardManager) : _displayRef(display), _error(OK)
|
||||
, _displayColorInverted(false), _displayDimmed(false), _enabled(true), _refreshRateHz(1), _refreshInterval(1000), _timeRef(0),_forceRefresh(false)
|
||||
, _currentView(NO_CURRENT_VIEW), _tail(NULL)
|
||||
, _viewNotFound{&(displayError), (ErrorInfo *)malloc(sizeof(ErrorInfo)), RESERVED_VIEW_UID, NULL}
|
||||
, _viewFuncUndefined{&(displayError), (ErrorInfo *)malloc(sizeof(ErrorInfo)), RESERVED_VIEW_UID, NULL}
|
||||
, _currentViewUndefined{&(displayError), (ErrorInfo *)malloc(sizeof(ErrorInfo)), RESERVED_VIEW_UID, NULL}
|
||||
@ -8,6 +10,10 @@ ScreenManager::ScreenManager(Adafruit_SSD1306 &display, SDCardManager *sdCardMan
|
||||
,_sdCardManager(sdCardManager)
|
||||
{
|
||||
_viewLinkedList = (ViewLinkedList) createEmptyList();
|
||||
//We set the error messages :
|
||||
((ErrorInfo *)_viewNotFound.pData)->errorMessage = FPSTR("View does not exist");
|
||||
((ErrorInfo *)_viewFunctionFailedToExecute.pData)->errorMessage = FPSTR("View function failed\nto execute");
|
||||
((ErrorInfo *)_viewFuncUndefined.pData)->errorMessage = FPSTR("View function is NULL");
|
||||
}
|
||||
|
||||
boolean ScreenManager::init()
|
||||
@ -66,8 +72,8 @@ void ScreenManager::setDefault()
|
||||
|
||||
boolean ScreenManager::addView(boolean (*viewLogicFunction)(Adafruit_SSD1306&, void*), void *pData, const unsigned char UID)
|
||||
{
|
||||
ViewLink viewLink ={viewLogicFunction, pData, UID, NULL};
|
||||
addNewLinkAtTheEnd(&_viewLinkedList, viewLink);
|
||||
ViewLink viewLink ={viewLogicFunction, pData, UID, NULL, NULL};
|
||||
return addNewLinkAtTheEnd(&_viewLinkedList, viewLink);
|
||||
}
|
||||
|
||||
void *ScreenManager::createEmptyList()
|
||||
@ -87,33 +93,48 @@ boolean ScreenManager::addNewLinkAtTheEnd(ViewLinkedList *viewLinkedList, ViewLi
|
||||
//Because of the const member
|
||||
memcpy(newViewLink, &viewLink, sizeof(*newViewLink));
|
||||
|
||||
if(isListEmpty(*viewLinkedList))*viewLinkedList = newViewLink;
|
||||
else
|
||||
//If this is the first link
|
||||
if(isListEmpty(*viewLinkedList))
|
||||
{
|
||||
if((*viewLinkedList)->UID == newViewLink->UID)
|
||||
{
|
||||
ViewLink *link = *viewLinkedList;
|
||||
//The link list points to the first link (aka the head)
|
||||
*viewLinkedList = newViewLink;
|
||||
newViewLink->next = link->next;
|
||||
free(link);
|
||||
//The previous pointer is still NULL;
|
||||
//The _tail pointer is the same as the head one.
|
||||
_tail = *viewLinkedList;
|
||||
}
|
||||
else //If there are some links already
|
||||
{
|
||||
ViewLinkedList *cursor = viewLinkedList;
|
||||
ViewLink *previousLink = NULL;
|
||||
|
||||
while(*cursor != NULL)
|
||||
{
|
||||
previousLink = *cursor;
|
||||
//We check if the UID already exists, if yes we replace the link
|
||||
if((*cursor)->UID == newViewLink->UID)
|
||||
{
|
||||
ViewLink *toDelete = *cursor;
|
||||
*cursor = newViewLink;
|
||||
newViewLink->next = toDelete->next;
|
||||
newViewLink->previous = toDelete->previous;
|
||||
//We check if the link as a next link registered
|
||||
if(toDelete->next != NULL)
|
||||
{
|
||||
//We update it's previous link since it's going to be deleted
|
||||
toDelete->next->previous = newViewLink;
|
||||
}
|
||||
//We do not forget to check if the link replaced is also the tail, in this case, we must update the tail
|
||||
if(_tail == toDelete)_tail = newViewLink;
|
||||
free(toDelete);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ViewLinkedList cursor = *viewLinkedList;
|
||||
|
||||
while(cursor->next != NULL)
|
||||
{
|
||||
if(cursor->next->UID == newViewLink->UID)
|
||||
{
|
||||
ViewLink *link = cursor->next;
|
||||
cursor->next = newViewLink;
|
||||
newViewLink->next = link->next;
|
||||
free(link);
|
||||
return true;
|
||||
cursor = &(*cursor)->next;
|
||||
}
|
||||
cursor = cursor->next;
|
||||
}
|
||||
cursor->next = newViewLink;
|
||||
newViewLink->previous = previousLink;
|
||||
*cursor = newViewLink;
|
||||
//We need to update the tail
|
||||
_tail = newViewLink;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -128,25 +149,28 @@ boolean ScreenManager::removeLinkByUID(ViewLinkedList *viewLinkedList, const uns
|
||||
{
|
||||
if(isListEmpty(*viewLinkedList))return false;
|
||||
|
||||
if((*viewLinkedList)->UID == UID)
|
||||
{
|
||||
ViewLink *tmp = *viewLinkedList;
|
||||
*viewLinkedList = (*viewLinkedList)->next;
|
||||
free(tmp);
|
||||
return true;
|
||||
}
|
||||
ViewLinkedList *cursor = viewLinkedList;
|
||||
|
||||
ViewLinkedList cursor = *viewLinkedList;
|
||||
while(!isListEmpty(cursor->next))
|
||||
while(*cursor != NULL)
|
||||
{
|
||||
if(cursor->next->UID == UID)
|
||||
//We check if this is the link we want to delete
|
||||
if((*cursor)->UID == UID)
|
||||
{
|
||||
ViewLink *tmp = cursor->next;
|
||||
cursor->next = cursor->next->next;
|
||||
free(tmp);
|
||||
ViewLink *toDelete = *cursor;
|
||||
*cursor = (*cursor)->next;
|
||||
|
||||
if(toDelete->next != NULL)
|
||||
{
|
||||
//We update the previous link of the next member since it's going to be deleted
|
||||
toDelete->next->previous = toDelete->previous;
|
||||
}
|
||||
//We also update the tail if the link we delete was the tail
|
||||
if(_tail == toDelete)_tail = toDelete->previous;
|
||||
|
||||
free(toDelete);
|
||||
return true;
|
||||
}
|
||||
cursor = cursor->next;
|
||||
cursor = &(*cursor)->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -186,119 +210,135 @@ ViewLink* ScreenManager::getLinkByUID(ViewLinkedList viewLinkedList, const unsig
|
||||
return NULL;
|
||||
}
|
||||
|
||||
boolean ScreenManager::displayView(const int UID)
|
||||
void ScreenManager::run()
|
||||
{
|
||||
if(!_enabled) return true;
|
||||
//Reset draw settings:
|
||||
if((millis() - _timeRef < _refreshInterval && !_forceRefresh) || !_enabled) return;
|
||||
|
||||
_timeRef = millis();
|
||||
|
||||
if(((_error == OK || _error == VIEW_FAILED_TO_EXECUTE) || _forceRefresh) && _currentView != NO_CURRENT_VIEW)
|
||||
{
|
||||
_displayRef.clearDisplay();
|
||||
_displayRef.setCursor(0,0);
|
||||
_displayRef.setTextSize(1);
|
||||
|
||||
|
||||
if(UID == -1 && _currentView == NO_CURRENT_VIEW)
|
||||
switch(_error)
|
||||
{
|
||||
//We display an error message on the screen
|
||||
((ErrorInfo *)_currentViewUndefined.pData)->errorMessage = FPSTR("Could not display current view");
|
||||
((ErrorInfo *)_currentViewUndefined.pData)->viewUID = UID;
|
||||
(*_currentViewUndefined.viewLogicFunction)(_displayRef, _currentViewUndefined.pData);
|
||||
_displayRef.display();
|
||||
|
||||
_error = CURRENT_VIEW_UNDEFINED;
|
||||
return false;
|
||||
}
|
||||
else if(UID == -1)
|
||||
case OK:
|
||||
case VIEW_FAILED_TO_EXECUTE:
|
||||
if(!(*_currentView->viewLogicFunction)(_displayRef, _currentView->pData))
|
||||
{
|
||||
if(_currentView->viewLogicFunction == NULL)
|
||||
{
|
||||
//We display an error message on the screen
|
||||
((ErrorInfo *)_viewFuncUndefined.pData)->errorMessage = FPSTR("View function is NULL");
|
||||
((ErrorInfo *)_viewFuncUndefined.pData)->viewUID = _currentView->UID;
|
||||
(*_viewFuncUndefined.viewLogicFunction)(_displayRef, _viewFuncUndefined.pData);
|
||||
_displayRef.display();
|
||||
|
||||
_error = VIEW_FUNC_UNDEFINED;
|
||||
return false;
|
||||
}
|
||||
else if(!(*_currentView->viewLogicFunction)(_displayRef, _currentView->pData))
|
||||
{
|
||||
//We display an error message on the screen
|
||||
_displayRef.clearDisplay();
|
||||
((ErrorInfo *)_viewFunctionFailedToExecute.pData)->errorMessage = FPSTR("View function failed\nto execute");
|
||||
//Error while executing the view function
|
||||
((ErrorInfo *)_viewFunctionFailedToExecute.pData)->viewUID = _currentView->UID;
|
||||
(*_viewFunctionFailedToExecute.viewLogicFunction)(_displayRef, _viewFunctionFailedToExecute.pData);
|
||||
_displayRef.display();
|
||||
|
||||
_error = VIEW_FAILED_TO_EXECUTE;
|
||||
return false;
|
||||
}
|
||||
|
||||
else
|
||||
_error = OK;
|
||||
_displayRef.display();
|
||||
return true;
|
||||
break;
|
||||
case VIEW_NOT_FOUND:
|
||||
(*_viewNotFound.viewLogicFunction)(_displayRef, _viewNotFound.pData);
|
||||
break;
|
||||
case VIEW_FUNC_UNDEFINED:
|
||||
(*_viewFuncUndefined.viewLogicFunction)(_displayRef, _viewFuncUndefined.pData);
|
||||
break;
|
||||
}
|
||||
|
||||
_displayRef.display();
|
||||
_forceRefresh = false;
|
||||
}
|
||||
}
|
||||
|
||||
boolean ScreenManager::displayView(const uint8_t UID)
|
||||
{
|
||||
if(!_enabled) return true;
|
||||
_forceRefresh = true;
|
||||
ViewLink *viewLink = getLinkByUID(_viewLinkedList, UID);
|
||||
|
||||
if(viewLink == NULL)
|
||||
{
|
||||
//We display an error message on the screen
|
||||
((ErrorInfo *)_viewNotFound.pData)->errorMessage = FPSTR("View does not exist");
|
||||
((ErrorInfo *)_viewNotFound.pData)->viewUID = UID;
|
||||
(*_viewNotFound.viewLogicFunction)(_displayRef, _viewNotFound.pData);
|
||||
_displayRef.display();
|
||||
|
||||
_error = VIEW_NOT_FOUND;
|
||||
_currentView = &_viewNotFound;
|
||||
return false;
|
||||
}else if(viewLink->viewLogicFunction == NULL)
|
||||
}
|
||||
else if(viewLink->viewLogicFunction == NULL)
|
||||
{
|
||||
//We display an error message on the screen
|
||||
((ErrorInfo *)_viewFuncUndefined.pData)->errorMessage = FPSTR("View function is NULL");
|
||||
((ErrorInfo *)_viewFuncUndefined.pData)->viewUID = UID;
|
||||
(*_viewFuncUndefined.viewLogicFunction)(_displayRef, _viewFuncUndefined.pData);
|
||||
_displayRef.display();
|
||||
|
||||
_error = VIEW_FUNC_UNDEFINED;
|
||||
_currentView = viewLink;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if(!(*viewLink->viewLogicFunction)(_displayRef, viewLink->pData))
|
||||
{
|
||||
//We display an error message on the screen
|
||||
_displayRef.clearDisplay();
|
||||
((ErrorInfo *)_viewFunctionFailedToExecute.pData)->errorMessage = FPSTR("View function failed\nto execute");
|
||||
((ErrorInfo *)_viewFunctionFailedToExecute.pData)->viewUID = UID;
|
||||
(*_viewFunctionFailedToExecute.viewLogicFunction)(_displayRef, _viewFunctionFailedToExecute.pData);
|
||||
_displayRef.display();
|
||||
|
||||
_error = VIEW_FAILED_TO_EXECUTE;
|
||||
_currentView = viewLink;
|
||||
return false;
|
||||
}
|
||||
|
||||
_displayRef.display();
|
||||
_currentView = viewLink;
|
||||
_error = OK;
|
||||
return true;
|
||||
run();
|
||||
return _error == OK;
|
||||
}
|
||||
|
||||
boolean ScreenManager::displayNextView()
|
||||
void ScreenManager::displayNextView()
|
||||
{
|
||||
_forceRefresh = true;
|
||||
_error = OK;
|
||||
if(_currentView == NO_CURRENT_VIEW && !isListEmpty(_viewLinkedList))
|
||||
{
|
||||
_currentView = _viewLinkedList;
|
||||
return displayView();
|
||||
}
|
||||
|
||||
if(!isListEmpty(_currentView->next))
|
||||
else if(!isListEmpty(_currentView->next))
|
||||
{
|
||||
_currentView = _currentView->next;
|
||||
return displayView();
|
||||
}
|
||||
//End of the views, we cycle again :)
|
||||
else if(isListEmpty(_currentView->next) && !isListEmpty(_viewLinkedList))
|
||||
{
|
||||
_currentView = _viewLinkedList;
|
||||
}
|
||||
|
||||
_currentView = _viewLinkedList;
|
||||
return displayView();
|
||||
//We check if the view function is defined :
|
||||
if(_currentView != NO_CURRENT_VIEW)
|
||||
{
|
||||
if(_currentView->viewLogicFunction == NULL)
|
||||
{
|
||||
((ErrorInfo *)_viewFuncUndefined.pData)->viewUID = _currentView->UID;
|
||||
_error = VIEW_FUNC_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
||||
}
|
||||
|
||||
void ScreenManager::displayPreviousView()
|
||||
{
|
||||
_forceRefresh = true;
|
||||
_error = OK;
|
||||
if(_currentView == NO_CURRENT_VIEW && !isListEmpty(_tail))
|
||||
{
|
||||
_currentView = _tail;
|
||||
}
|
||||
else if(!isListEmpty(_currentView->previous))
|
||||
{
|
||||
_currentView = _currentView->previous;
|
||||
}
|
||||
//End of the views, we cycle again :)
|
||||
else if(isListEmpty(_currentView->previous) && !isListEmpty(_tail))
|
||||
{
|
||||
_currentView = _tail;
|
||||
}
|
||||
|
||||
//We check if the view function is defined :
|
||||
if(_currentView != NO_CURRENT_VIEW)
|
||||
{
|
||||
if(_currentView->viewLogicFunction == NULL)
|
||||
{
|
||||
((ErrorInfo *)_viewFuncUndefined.pData)->viewUID = _currentView->UID;
|
||||
_error = VIEW_FUNC_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
||||
}
|
||||
|
||||
void ScreenManager::invertDisplayColor(const boolean inverted)
|
||||
@ -354,6 +394,20 @@ void ScreenManager::clearDisplay(const boolean bufferOnly)
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::clearViews()
|
||||
{
|
||||
ViewLinkedList cursor = _viewLinkedList;
|
||||
while(!isListEmpty(cursor))
|
||||
{
|
||||
ViewLink *toDelete = cursor;
|
||||
cursor = cursor->next;
|
||||
free(cursor);
|
||||
}
|
||||
//Do not forget to mark the list as empty
|
||||
_viewLinkedList = NULL;
|
||||
_tail = NULL;
|
||||
}
|
||||
|
||||
void ScreenManager::setEnabled(boolean value)
|
||||
{
|
||||
_enabled = value;
|
||||
|
@ -16,18 +16,21 @@ class ScreenManager
|
||||
|
||||
boolean addView(boolean (*viewLogicFunction)(Adafruit_SSD1306&, void*), void *pData, const unsigned char UID);
|
||||
boolean removeView(const unsigned char UID);
|
||||
boolean displayView(const int UID = -1);
|
||||
boolean displayNextView();
|
||||
boolean displayView(const uint8_t UID);
|
||||
void displayNextView();
|
||||
void displayPreviousView();
|
||||
boolean applyCfgFromSD();
|
||||
void invertDisplayColor(const boolean inverted);
|
||||
void orientDisplay(const Orientation orientation);
|
||||
void dimDisplay(const boolean dimmed);
|
||||
void clearDisplay(const boolean bufferOnly = false);
|
||||
void clearViews();
|
||||
void sleep();
|
||||
void wakeUp();
|
||||
void setEnabled(boolean value);
|
||||
boolean getEnabled();
|
||||
boolean init();
|
||||
void run();
|
||||
|
||||
Error getError() const;
|
||||
const char* getErrorMessage() const;
|
||||
@ -58,7 +61,11 @@ class ScreenManager
|
||||
boolean _displayColorInverted;
|
||||
boolean _displayDimmed;
|
||||
boolean _enabled;
|
||||
ViewLink* _currentView;
|
||||
uint8_t _refreshRateHz;
|
||||
uint16_t _refreshInterval;
|
||||
uint64_t _timeRef;
|
||||
boolean _forceRefresh;
|
||||
ViewLink *_currentView, *_tail;
|
||||
ViewLink _viewNotFound, _viewFuncUndefined, _currentViewUndefined, _viewFunctionFailedToExecute;
|
||||
SDCardManager *_sdCardManager;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user