diff --git a/apps/code/script_store.cpp b/apps/code/script_store.cpp index 587aa1526..ba523f577 100644 --- a/apps/code/script_store.cpp +++ b/apps/code/script_store.cpp @@ -109,27 +109,20 @@ bool ScriptStore::isFull() { return (numberOfScripts() >= k_maxNumberOfScripts || m_accordion.freeSpaceSize() < k_fullFreeSpaceSizeLimit); } -void ScriptStore::scanScriptsForFunctionsAndVariables( - void * context, - FunctionCallTwoIntArgs storeFunctionsCountForScriptAtIndex, - FunctionCallOneIntOneConstCharPointerArg storeFunctionNameStartAtIndex, - FunctionCallTwoIntArgs storeGlobalVariablesCountForScriptAtIndex, - FunctionCallOneIntOneConstCharPointerArg storeGlobalVariableNameStartAtIndex - ) { - int totalFunctionsCount = 0; - int totalGlobalVariablesCount = 0; +void ScriptStore::scanScriptsForFunctionsAndVariables(void * context, ScanCallback storeFunction, ScanCallback storeVariable) { for (int scriptIndex = 0; scriptIndex < numberOfScripts(); scriptIndex++) { // Handle lexer or parser errors with nlr. nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { const char * scriptContent = scriptAtIndex(scriptIndex).content(); + if (scriptContent == nullptr) { + continue; + } mp_lexer_t *lex = mp_lexer_new_from_str_len(0, scriptContent, strlen(scriptContent), false); mp_parse_tree_t parseTree = mp_parse(lex, MP_PARSE_FILE_INPUT); mp_parse_node_t pn = parseTree.root; if (!MP_PARSE_NODE_IS_STRUCT(pn)) { - storeFunctionsCountForScriptAtIndex(context, scriptIndex, 0); - storeGlobalVariablesCountForScriptAtIndex(context, scriptIndex, 0); mp_parse_tree_clear(&parseTree); nlr_pop(); continue; @@ -143,10 +136,7 @@ void ScriptStore::scanScriptsForFunctionsAndVariables( if (id == nullptr) { continue; } - storeFunctionsCountForScriptAtIndex(context, scriptIndex, 1); - storeFunctionNameStartAtIndex(context, totalFunctionsCount, id); - totalFunctionsCount++; - storeGlobalVariablesCountForScriptAtIndex(context, scriptIndex, 0); + storeFunction(context, id, scriptIndex); mp_parse_tree_clear(&parseTree); nlr_pop(); continue; @@ -158,10 +148,7 @@ void ScriptStore::scanScriptsForFunctionsAndVariables( if (id == nullptr) { continue; } - storeGlobalVariablesCountForScriptAtIndex(context, scriptIndex, 1); - storeGlobalVariableNameStartAtIndex(context, totalGlobalVariablesCount, id); - totalGlobalVariablesCount++; - storeFunctionsCountForScriptAtIndex(context, scriptIndex, 0); + storeVariable(context, id, scriptIndex); mp_parse_tree_clear(&parseTree); nlr_pop(); continue; @@ -170,16 +157,12 @@ void ScriptStore::scanScriptsForFunctionsAndVariables( if (((uint)(MP_PARSE_NODE_STRUCT_KIND(pns))) != k_fileInput2ParseNodeStructKind) { // The script node is not of type "file_input_2", thus it will not have main // structures of the wanted type. - storeFunctionsCountForScriptAtIndex(context, scriptIndex, 0); - storeGlobalVariablesCountForScriptAtIndex(context, scriptIndex, 0); mp_parse_tree_clear(&parseTree); nlr_pop(); continue; } // Count the number of structs in child nodes. - int numberOfFunctionsInCurrentScript = 0; - int numberOfGlobalVariablesInCurrentScript = 0; size_t n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); for (size_t i = 0; i < n; i++) { @@ -191,30 +174,19 @@ void ScriptStore::scanScriptsForFunctionsAndVariables( if (id == nullptr) { continue; } - storeFunctionNameStartAtIndex(context, totalFunctionsCount, id); - numberOfFunctionsInCurrentScript++; - totalFunctionsCount++; + storeFunction(context, id, scriptIndex); } else if (((uint)(MP_PARSE_NODE_STRUCT_KIND(child_pns))) == k_expressionStatementParseNodeStructKind) { const char * id = structID(child_pns); if (id == nullptr) { continue; } - storeGlobalVariableNameStartAtIndex(context, totalGlobalVariablesCount, id); - numberOfGlobalVariablesInCurrentScript++; - totalGlobalVariablesCount++; + storeVariable(context, id, scriptIndex); } } } - storeFunctionsCountForScriptAtIndex(context, scriptIndex, numberOfFunctionsInCurrentScript); - storeGlobalVariablesCountForScriptAtIndex(context, scriptIndex, numberOfGlobalVariablesInCurrentScript); - mp_parse_tree_clear(&parseTree); nlr_pop(); - } else { - // The lexer or the parser failed. - storeFunctionsCountForScriptAtIndex(context, scriptIndex, 0); - storeGlobalVariablesCountForScriptAtIndex(context, scriptIndex, 0); } } } diff --git a/apps/code/script_store.h b/apps/code/script_store.h index dd3bcc22b..d8c26c2b1 100644 --- a/apps/code/script_store.h +++ b/apps/code/script_store.h @@ -35,15 +35,8 @@ public: bool isFull(); /* Provide scripts content information */ - typedef void (* FunctionCallTwoIntArgs)(void * context, int n1, int n2); - typedef void (* FunctionCallOneIntOneConstCharPointerArg)(void * context, int n, const char * p1); - void scanScriptsForFunctionsAndVariables( - void * context, - FunctionCallTwoIntArgs storeFunctionsCountForScriptAtIndex, - FunctionCallOneIntOneConstCharPointerArg storeFunctionNameStartAtIndex, - FunctionCallTwoIntArgs storeGlobalVariablesCountForScriptAtIndex, - FunctionCallOneIntOneConstCharPointerArg storeGlobalVariableNameStartAtIndex - ); + typedef void (* ScanCallback)(void * context, const char * p, int n); + void scanScriptsForFunctionsAndVariables(void * context, ScanCallback storeFunction,ScanCallback storeVariable); /* MicroPython::ScriptProvider */ const char * contentOfScript(const char * name) override; diff --git a/apps/code/variable_box_controller.cpp b/apps/code/variable_box_controller.cpp index f4397fe46..bbcd6e9cb 100644 --- a/apps/code/variable_box_controller.cpp +++ b/apps/code/variable_box_controller.cpp @@ -14,23 +14,11 @@ namespace Code { VariableBoxController::ContentViewController::ContentViewController(Responder * parentResponder, MenuController * menuController, ScriptStore * scriptStore) : ViewController(parentResponder), - m_currentDepth(0), - m_firstSelectedRow(0), - m_previousSelectedRow(0), - m_scriptFunctionsCount(-1), - m_scriptVariablesCount(-1), + m_scriptNodesCount(0), m_menuController(menuController), m_scriptStore(scriptStore), m_selectableTableView(this, this, 0, 1, 0, 0, 0, 0, this, nullptr, false) { - for (int i = 0; i < ScriptStore::k_maxNumberOfScripts; i++) { - m_functionDefinitionsCount[i] = 0; - m_globalVariablesCount[i] = 0; - } - for (int i = 0; i < k_functionsAndVarsNamePointersArrayLength; i++) { - m_functionNamesPointers[i] = nullptr; - m_globalVariablesNamesPointers[i] = nullptr; - } for (int i = 0; i < k_maxNumberOfDisplayedRows; i++) { m_leafCells[i].setFirstTextColor(KDColorBlack); m_leafCells[i].setSecondTextColor(Palette::GreyDark); @@ -51,30 +39,14 @@ void VariableBoxController::ContentViewController::reloadData() { m_selectableTableView.reloadData(); } -void VariableBoxController::ContentViewController::resetDepth() { - m_currentDepth = 0; +void VariableBoxController::ContentViewController::addFunctionAtIndex(const char * functionName, int scriptIndex) { + m_scriptNodes[m_scriptNodesCount] = ScriptNode::FunctionNode(functionName, scriptIndex); + m_scriptNodesCount++; } -void VariableBoxController::ContentViewController::setFunctionsCountInScriptAtIndex(int functionsCount, int scriptIndex) { - assert(functionsCount >= 0); - assert(scriptIndex >= 0 && scriptIndex < ScriptStore::k_maxNumberOfScripts); - m_functionDefinitionsCount[scriptIndex] = functionsCount; -} - -void VariableBoxController::ContentViewController::setFunctionNameAtIndex(const char * functionName, int functionIndex) { - assert(functionIndex >= 0 && functionIndex < k_functionsAndVarsNamePointersArrayLength); - m_functionNamesPointers[functionIndex] = functionName; -} - -void VariableBoxController::ContentViewController::setGlobalVariablesCountInScriptAtIndex(int globalVariablesCount, int scriptIndex) { - assert(globalVariablesCount >= 0); - assert(scriptIndex >= 0 && scriptIndex < ScriptStore::k_maxNumberOfScripts); - m_globalVariablesCount[scriptIndex] = globalVariablesCount; -} - -void VariableBoxController::ContentViewController::setGlobalVariableNameAtIndex(const char * globalVariableName, int globalVariableIndex) { - assert(globalVariableIndex >= 0 && globalVariableIndex < k_functionsAndVarsNamePointersArrayLength); - m_globalVariablesNamesPointers[globalVariableIndex] = globalVariableName; +void VariableBoxController::ContentViewController::addVariableAtIndex(const char * variableName, int scriptIndex) { + m_scriptNodes[m_scriptNodesCount] = ScriptNode::VariableNode(variableName, scriptIndex); + m_scriptNodesCount++; } const char * VariableBoxController::ContentViewController::title() { @@ -83,35 +55,15 @@ const char * VariableBoxController::ContentViewController::title() { void VariableBoxController::ContentViewController::viewWillAppear() { m_menuController->loadPythonIfNeeded(); - for (int i = 0; i < ScriptStore::k_maxNumberOfScripts; i++) { - m_functionDefinitionsCount[i] = 0; - m_globalVariablesCount[i] = 0; - } + m_scriptNodesCount = 0; m_scriptStore->scanScriptsForFunctionsAndVariables( - this, - [](void * context, int scriptIndex, int functionsCount) { + this, + [](void * context, const char * functionName, int scriptIndex) { VariableBoxController::ContentViewController * cvc = static_cast(context); - cvc->setFunctionsCountInScriptAtIndex(functionsCount, scriptIndex); - }, - [](void * context, int functionIndex, const char * functionName) { + cvc->addFunctionAtIndex(functionName, scriptIndex);}, + [](void * context, const char * variableName, int scriptIndex) { VariableBoxController::ContentViewController * cvc = static_cast(context); - cvc->setFunctionNameAtIndex(functionName, functionIndex); - }, - [](void * context, int scriptIndex, int globalVariablesCount) { - VariableBoxController::ContentViewController * cvc = static_cast(context); - cvc->setGlobalVariablesCountInScriptAtIndex(globalVariablesCount, scriptIndex); - }, - [](void * context, int globalVariableIndex, const char * globalVariableName) { - VariableBoxController::ContentViewController * cvc = static_cast(context); - cvc->setGlobalVariableNameAtIndex(globalVariableName, globalVariableIndex); - }); - - m_scriptFunctionsCount = 0; - m_scriptVariablesCount = 0; - for (int i = 0; i < ScriptStore::k_maxNumberOfScripts; i++) { - m_scriptFunctionsCount+= m_functionDefinitionsCount[i]; - m_scriptVariablesCount+= m_globalVariablesCount[i]; - } + cvc->addVariableAtIndex(variableName, scriptIndex);}); } void VariableBoxController::ContentViewController::viewDidDisappear() { @@ -122,43 +74,22 @@ void VariableBoxController::ContentViewController::viewDidDisappear() { void VariableBoxController::ContentViewController::didBecomeFirstResponder() { m_selectableTableView.reloadData(); m_selectableTableView.scrollToCell(0,0); - selectCellAtLocation(0, m_firstSelectedRow); + selectCellAtLocation(0, 0); app()->setFirstResponder(&m_selectableTableView); } bool VariableBoxController::ContentViewController::handleEvent(Ion::Events::Event event) { - if (event == Ion::Events::Back && m_currentDepth == 0) { - m_firstSelectedRow = 0; + if (event == Ion::Events::Back) { app()->dismissModalViewController(); return true; } - if (event == Ion::Events::Left && m_currentDepth == 0) { + if (event == Ion::Events::Left) { return true; } - if (event == Ion::Events::Back || event == Ion::Events::Left) { - assert(m_currentDepth == 1); - m_firstSelectedRow = m_previousSelectedRow; - m_selectableTableView.deselectTable(); - m_currentDepth = 0; - app()->setFirstResponder(this); - return true; - } - if (event == Ion::Events::OK || event == Ion::Events::EXE || (event == Ion::Events::Right && m_currentDepth == 0)) { - if (m_currentDepth == 0) { - // Select a submenu from the Root Menu - m_previousSelectedRow = selectedRow(); - m_firstSelectedRow = 0; - m_selectableTableView.deselectTable(); - m_currentDepth = 1; - app()->setFirstResponder(this); - return true; - } - // Select a leaf in a submenu - m_firstSelectedRow = 0; + if (event == Ion::Events::OK || event == Ion::Events::EXE) { DoubleBufferTextCell * selectedTextCell = static_cast(m_selectableTableView.selectedCell()); insertTextInCaller(selectedTextCell->firstText()); m_selectableTableView.deselectTable(); - m_currentDepth = 0; app()->dismissModalViewController(); return true; } @@ -166,66 +97,24 @@ bool VariableBoxController::ContentViewController::handleEvent(Ion::Events::Even } int VariableBoxController::ContentViewController::numberOfRows() { - if (m_currentDepth == 0) { - return k_numberOfMenuRows; - } - assert(m_currentDepth == 1); - if (m_previousSelectedRow == 0) { - return m_scriptFunctionsCount; - } - assert(m_previousSelectedRow == 1); - return m_scriptVariablesCount; + return m_scriptNodesCount < k_maxScriptNodesCount ? m_scriptNodesCount : k_maxScriptNodesCount; } HighlightCell * VariableBoxController::ContentViewController::reusableCell(int index, int type) { - assert(type < 2); - assert(index >= 0); - if (type == k_leafType) { - assert(index < k_maxNumberOfDisplayedRows); - return &m_leafCells[index]; - } - assert(type == k_nodeType); - assert(index < k_numberOfMenuRows); - return &m_nodeCells[index]; + assert(type == k_leafType); + assert(index >= 0 && index < k_maxNumberOfDisplayedRows); + return &m_leafCells[index]; } int VariableBoxController::ContentViewController::reusableCellCount(int type) { - assert(type < 2); - if (type == k_leafType) { - return k_maxNumberOfDisplayedRows; - } - assert (type == k_nodeType); - return k_numberOfMenuRows; + assert(type == k_leafType); + return k_maxNumberOfDisplayedRows; } void VariableBoxController::ContentViewController::willDisplayCellForIndex(HighlightCell * cell, int index) { - if (m_currentDepth == 0) { - MessageTableCellWithChevron * myCell = static_cast(cell); - I18n::Message nodeMessages[2] = {I18n::Message::Functions, I18n::Message::Variables}; - myCell->setMessage(nodeMessages[index]); - return; - } - assert(m_currentDepth == 1); DoubleBufferTextCell * myCell = static_cast(cell); - if (m_previousSelectedRow == 0) { - myCell->setFirstText(m_functionNamesPointers[index]); - int scriptIndex = -1; - int functionsCount = 0; - while (functionsCount < index + 1 && scriptIndex < ScriptStore::k_maxNumberOfScripts) { - scriptIndex++; - functionsCount+= m_functionDefinitionsCount[scriptIndex]; - } - myCell->setSecondText(m_scriptStore->scriptAtIndex(scriptIndex).name()); - } else { - myCell->setFirstText(m_globalVariablesNamesPointers[index]); - int scriptIndex = -1; - int globalVariablesCount = 0; - while (globalVariablesCount < index + 1 && scriptIndex < ScriptStore::k_maxNumberOfScripts) { - scriptIndex++; - globalVariablesCount+= m_globalVariablesCount[scriptIndex]; - } - myCell->setSecondText(m_scriptStore->scriptAtIndex(scriptIndex).name()); - } + myCell->setFirstText(m_scriptNodes[index].name()); + myCell->setSecondText(m_scriptStore->scriptAtIndex(m_scriptNodes[index].scriptIndex()).name()); } KDCoordinate VariableBoxController::ContentViewController::rowHeight(int index) { @@ -250,9 +139,6 @@ int VariableBoxController::ContentViewController::indexFromCumulatedHeight(KDCoo } int VariableBoxController::ContentViewController::typeAtLocation(int i, int j) { - if (m_currentDepth == 0) { - return k_nodeType; - } return k_leafType; } @@ -296,7 +182,6 @@ void VariableBoxController::setTextAreaCaller(TextArea * textArea) { void VariableBoxController::viewWillAppear() { StackViewController::viewWillAppear(); - m_contentViewController.resetDepth(); m_contentViewController.reloadData(); } diff --git a/apps/code/variable_box_controller.h b/apps/code/variable_box_controller.h index d14b6049a..f21eb4abb 100644 --- a/apps/code/variable_box_controller.h +++ b/apps/code/variable_box_controller.h @@ -23,12 +23,9 @@ private: void setTextFieldCaller(TextField * textField); void setTextAreaCaller(TextArea * textArea); void reloadData(); - void resetDepth(); - void setFunctionsCountInScriptAtIndex(int functionsCount, int scriptIndex); - void setFunctionNameAtIndex(const char * functionName, int functionIndex); - void setGlobalVariablesCountInScriptAtIndex(int scriptIndex, int globalVariablesCount); - void setGlobalVariableNameAtIndex(const char * globalVariableName, int globalVariableIndex); + void addFunctionAtIndex(const char * functionName, int scriptIndex); + void addVariableAtIndex(const char * variableName, int scriptIndex); /* ViewController */ const char * title() override; @@ -50,29 +47,42 @@ private: int indexFromCumulatedHeight(KDCoordinate offsetY) override; int typeAtLocation(int i, int j) override; private: + class ScriptNode { + public: + enum class Type { + Function = 0, + Variable = 1 + }; + ScriptNode() : + m_type(Type::Function), m_name(nullptr), m_scriptIndex(0) {} + static ScriptNode FunctionNode(const char * name, uint16_t scriptIndex) { + return ScriptNode(Type::Function, name, scriptIndex); + } + static ScriptNode VariableNode(const char * name, uint16_t scriptIndex) { + return ScriptNode(Type::Variable, name, scriptIndex); + } + Type type() const { return m_type; } + const char * name() const { return m_name; } + uint16_t scriptIndex() const { return m_scriptIndex; } + private: + ScriptNode(Type type, const char * name, uint16_t scriptIndex) : + m_type(type), m_name(name), m_scriptIndex(scriptIndex) {} + Type m_type; + const char * m_name; + uint16_t m_scriptIndex; + }; + constexpr static int k_maxNumberOfDisplayedRows = 6; //240/40 - constexpr static int k_numberOfMenuRows = 2; - constexpr static int k_nodeType = 0; - constexpr static int k_leafType = 1; - constexpr static int k_functionsAndVarsNamePointersArrayLength = 32; + constexpr static int k_leafType = 0; + constexpr static int k_maxScriptNodesCount = 32; void insertTextInCaller(const char * text); - int m_currentDepth; - int m_firstSelectedRow; - int m_previousSelectedRow; - int m_scriptFunctionsCount; - int m_scriptVariablesCount; - - int m_functionDefinitionsCount[ScriptStore::k_maxNumberOfScripts]; - int m_globalVariablesCount[ScriptStore::k_maxNumberOfScripts]; - const char * m_functionNamesPointers[k_functionsAndVarsNamePointersArrayLength]; - const char * m_globalVariablesNamesPointers[k_functionsAndVarsNamePointersArrayLength]; - + int m_scriptNodesCount; + ScriptNode m_scriptNodes[k_maxScriptNodesCount]; MenuController * m_menuController; ScriptStore * m_scriptStore; TextField * m_textFieldCaller; TextArea * m_textAreaCaller; DoubleBufferTextCell m_leafCells[k_maxNumberOfDisplayedRows]; - MessageTableCellWithChevron m_nodeCells[k_numberOfMenuRows]; SelectableTableView m_selectableTableView; }; ContentViewController m_contentViewController;