Repository for import to local machine
Dependencies: DMBasicGUI DMSupport
Diff: DebugCommandsPageHandler.cpp
- Revision:
- 1:a5258871b33d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DebugCommandsPageHandler.cpp Thu Jul 20 08:42:29 2017 +0000 @@ -0,0 +1,260 @@ +#include "DebugCommandsPageHandler.h" +#include "EasyGUITouchAreaIndices.h" +#include "GetGCStatusLoop.h" +#include "DebugCommandsPageHandler.h" +#include "USBHostGCUtilities.h" + +// main.cpp +void SpecialDebugPrint(char *stuffToPrint, GuiConst_INT16S X, GuiConst_INT16S Y); + +/* + Draws the default background bitmap, i.e. *without* the Ellutia logo. + Defined in main.cpp +*/ +void DrawBackgroundBitmap(void); + + +/* + Note that this class is a singleton - we do not need or want there to be more than one instance of it + (we do not want multiple values for the same nudge and damp parameters, etc, nor will we show + more than one easyGUI page to the user at the same time). +*/ +DebugCommandsPageHandler * DebugCommandsPageHandler::theDebugCommandsPageHandlerInstance = NULL; + + +/* + Singleton class - return the one and only instance, first creating it if necessary. +*/ +DebugCommandsPageHandler * DebugCommandsPageHandler::GetInstance(USBDeviceConnected* newUsbDevice, USBHostGC* newUsbHostGC) +{ + if (theDebugCommandsPageHandlerInstance == NULL) { + theDebugCommandsPageHandlerInstance = new DebugCommandsPageHandler(newUsbDevice, newUsbHostGC); + } + + return theDebugCommandsPageHandlerInstance; +} + +/* + Overriden version of the above, that does not take any arguments and does not create the instance + if it does not already exist. Caller *must* check for NULL. + + Provided for callers that do not have the 'usbDevice' and 'usbHostGC' pointers, and just want access + to the instance if it exists +*/ +DebugCommandsPageHandler * DebugCommandsPageHandler::GetInstance(void) +{ + return theDebugCommandsPageHandlerInstance; +} + + +// Singleton class - private constructor +DebugCommandsPageHandler::DebugCommandsPageHandler(USBDeviceConnected* newUsbDevice, USBHostGC* newUsbHostGC) +{ + usbDevice = newUsbDevice; + usbHostGC = newUsbHostGC; + + // Set this true immediately after executing a GC command. + // If the user types another char, clear the command first. + commandJustExecuted = false; +} + + +// Private destructor also +DebugCommandsPageHandler::~DebugCommandsPageHandler() +{ +} + +/* + As the name implies, sends a command to the GC and displays the response. + Expects the command to be in the easyGUI variable "GuiVar_debugCommandTx", + and places the response in the easyGUI variable "GuiVar_debugCommandRx". + It is up to the caller to (re)display the Debug Commands easyGUI page + to show the updated values. + + Args: pointer to a buffer containing the command, as a null-terminated string + pointer to a buffer to contain the response, as a null-terminated string + + No return code (it is up to the caller to examine the response to see whether + the command succeeded or failed) +*/ +void DebugCommandsPageHandler::SendCommandToGCAndDisplayResponse(void) +{ + char command[20]; + char response[20]; + + strcpy(command, GuiVar_debugCommandTx); + + bool expect4Chars = ((command[0] == 'C') || (command[0] == 'S')); + // Else expect 8 chars (or "EPKT") + +#define USE_GC_UTILS // Testing new class +#ifdef USE_GC_UTILS + USBHostGCUtilities::SendCommandToGCAndGetResponse(usbDevice, usbHostGC, command, response); +#else + while(usbHostGC->ExecutingSetDeviceReport()) {} + + usbHostGC->SetDeviceReport(usbDevice, command, response); +#endif // USE_GC_UTILS + + // There always seems to be garbage at the end of the response + if(expect4Chars || (response[0] == 'E')) { // If 'E', assume "EPKT" + response[4] = '\0'; + } else { + response[8] = '\0'; + } + +//#define DEBUG_PRINT_HERE +#ifdef DEBUG_PRINT_HERE + char dbg[100]; + sprintf(dbg, "DCPH cmd \"%s\", response \"%s\"", command, response); + SpecialDebugPrint(dbg, 10, 275); +#endif // DEBUG_PRINT_HERE + + strcpy(GuiVar_debugCommandRx, response); + + commandJustExecuted = true; +} + + +/* + Tells the caller whether or not the specified touch index is on the Debug Commands page, + and therefore needs to be handled by this class. + + Args: the touch area index in question + + Return code: true if the touch area is 'one of ours', false if not +*/ +bool DebugCommandsPageHandler::TouchAreaIsOnDebugCommandsPage(int touchAreaIndex) +{ + if((touchAreaIndex >= MIN_DEBUG_COMMANDS_TOUCHINDEX) && (touchAreaIndex <= MAX_DEBUG_COMMANDS_TOUCHINDEX)) { + return true; + } + + // 'else' + return false; +} + + +/* + Returns the character that matches the specified touch area index. + This should be one of the character keys on the easyGUI DebugCommandsPage. + If not, defaults to '0'. + + Args: the touch area index + + Returns the corresponding character if there is one, '0' if not +*/ +char DebugCommandsPageHandler::GetCharCodeForTouchAreaIndex(int touchAreaIndex) +{ + if((touchAreaIndex >= DEBUG_COMMANDS_0) && (touchAreaIndex <= DEBUG_COMMANDS_9)) { + return (touchAreaIndex - DEBUG_COMMANDS_0 + '0'); + } + + // else... + if((touchAreaIndex >= DEBUG_COMMANDS_A) && (touchAreaIndex <= DEBUG_COMMANDS_Z)) { + return (touchAreaIndex - DEBUG_COMMANDS_A + 'A'); + } + + // else... + return '0'; +} + + +/* + If the specified touch area represents a key or field on the easyGUI Debug Commands page, + this function performs whatever action is appropriate for it. Provided so that the caller + can (in effect) say "if this is one of yours, deal with it", without needing to know + anything about what this class does, or how it handles the touch areas on that easyGUI page. + + Args: the touch area index in question + + Returns true if it dealt with the touch area (so the caller need not do anything else + with the value), or false if it did not deal with the touch area (implying that it + was not a touch area on the easyGUI GC/Debug Commands page, and so the caller + must deal with it some other way). +*/ +bool DebugCommandsPageHandler::DealWithTouch(int touchAreaIndex) +{ + if(touchAreaIndex == DEBUG_COMMANDS_SEND) { + + // Clear response first, so user sees something happen + GuiVar_debugCommandRx[0] = '\0'; + DisplayEasyGUIPage(); + + SendCommandToGCAndDisplayResponse(); + DisplayEasyGUIPage(); + + return true; + } + + // If a character, append it to GuiVar_debugCommandTx, unless that is already at MAX_COMMAND_LENGTH + if((touchAreaIndex >= MIN_DEBUG_COMMANDS_CHAR) && (touchAreaIndex <= MAX_DEBUG_COMMANDS_CHAR)) { + + // If we have just executed a command, start a new one as soon as the user types another character, + // but not if he types Delete or Clear (since he is in effect editing the previous command) + if(commandJustExecuted) { + GuiVar_debugCommandTx[0] = '\0'; // Clear the command we have just executed + + commandJustExecuted = false; // So we know to append subsequent characters to this one + } + + int len = strlen(GuiVar_debugCommandTx); + if(len < MAX_COMMAND_LENGTH) { + // Append the new character to the command + GuiVar_debugCommandTx[len] = GetCharCodeForTouchAreaIndex(touchAreaIndex); + GuiVar_debugCommandTx[len + 1] = '\0'; + + DisplayEasyGUIPage(); + } + return true; + } + + // If DEBUG_COMMANDS_DELETE, delete the last character in GuiVar_debugCommandTx, unless it already has zero characters + if((touchAreaIndex == DEBUG_COMMANDS_DELETE)) { + int len = strlen(GuiVar_debugCommandTx); + if(len > 0) { + // Delete the last character in the command + GuiVar_debugCommandTx[len - 1] = '\0'; + + DisplayEasyGUIPage(); + + commandJustExecuted = false; // User has (in effect) edited this command - do not start a new one if he types another character + } + return true; + } + + // If DEBUG_COMMANDS_CLEAR, clear the command by setting GuiVar_debugCommandTx to an empty string + if((touchAreaIndex == DEBUG_COMMANDS_CLEAR)) { + GuiVar_debugCommandTx[0] = '\0'; + DisplayEasyGUIPage(); + + commandJustExecuted = false; // User has (in effect) edited this command - do not start a new one if he types another character + return true; + } + + // 'else'... + + return false; +} + + +/* + (Re)display the easyGUI 'DebugCommandsPage' - e.g. after we have updated + the command to be sent, and want to display the new value to the user. + + No arguments, no return code +*/ +void DebugCommandsPageHandler::DisplayEasyGUIPage(void) +{ + DrawBackgroundBitmap(); + + GuiLib_ShowScreen(GuiStruct_DebugCommandsPage_Def, GuiLib_NO_CURSOR, GuiLib_RESET_AUTO_REDRAW); + + GuiLib_Refresh(); + + GetGCStatusLoop *getGCStatusLoop = GetGCStatusLoop::GetInstance(); + if(getGCStatusLoop != NULL) { + getGCStatusLoop->SetCurrentPage(GuiStruct_DebugCommandsPage_Def); + } +} +