diff --git a/apps/code/app.cpp b/apps/code/app.cpp index 64ef47859..bccf11716 100644 --- a/apps/code/app.cpp +++ b/apps/code/app.cpp @@ -113,7 +113,7 @@ Toolbox * App::toolboxForInputEventHandler(InputEventHandler * textInput) { return &m_toolbox; } -NestedMenuController * App::variableBoxForInputEventHandler(InputEventHandler * textInput) { +VariableBoxController * App::variableBoxForInputEventHandler(InputEventHandler * textInput) { return &m_variableBoxController; } diff --git a/apps/code/app.h b/apps/code/app.h index af4336713..bcb45c3ee 100644 --- a/apps/code/app.h +++ b/apps/code/app.h @@ -46,14 +46,19 @@ public: /* InputEventHandlerDelegate */ Toolbox * toolboxForInputEventHandler(InputEventHandler * textInput) override; - NestedMenuController * variableBoxForInputEventHandler(InputEventHandler * textInput) override; + VariableBoxController * variableBoxForInputEventHandler(InputEventHandler * textInput) override; + /* TextInputDelegate */ bool textInputDidReceiveEvent(InputEventHandler * textInput, Ion::Events::Event event); + + /* Code::App */ // Python delegate bool pythonIsInited() { return m_pythonUser != nullptr; } bool isPythonUser(const void * pythonUser) { return m_pythonUser == pythonUser; } void initPythonWithUser(const void * pythonUser); void deinitPython(); + + VariableBoxController * variableBoxController() { return &m_variableBoxController; } private: /* Python delegate: * MicroPython requires a heap. To avoid dynamic allocation, we keep a working diff --git a/apps/code/console_controller.cpp b/apps/code/console_controller.cpp index c0ae747b0..5a9a1e89d 100644 --- a/apps/code/console_controller.cpp +++ b/apps/code/console_controller.cpp @@ -105,6 +105,10 @@ const char * ConsoleController::inputText(const char * prompt) { void ConsoleController::viewWillAppear() { loadPythonEnvironment(); + /* We load functions and variables names in the variable box before running + * any other python code to avoid failling to load functions and variables + * due to memory exhaustion. */ + static_cast(app())->variableBoxController()->loadFunctionsAndVariables(); m_sandboxIsDisplayed = false; if (m_importScriptsWhenViewAppears) { m_importScriptsWhenViewAppears = false; diff --git a/apps/code/editor_controller.cpp b/apps/code/editor_controller.cpp index b08658822..3e07e0ad4 100644 --- a/apps/code/editor_controller.cpp +++ b/apps/code/editor_controller.cpp @@ -1,11 +1,12 @@ #include "editor_controller.h" #include "menu_controller.h" #include "script_parameter_controller.h" -#include "variable_box_controller.h" -#include +#include "app.h" #include #include +using namespace Shared; + namespace Code { EditorController::EditorController(MenuController * menuController, App * pythonDelegate) : @@ -14,7 +15,7 @@ EditorController::EditorController(MenuController * menuController, App * python m_script(Ion::Storage::Record()), m_menuController(menuController) { - m_editorView.setTextAreaDelegates(pythonDelegate, this); + m_editorView.setTextAreaDelegates(this, this); } void EditorController::setScript(Script script) { @@ -127,6 +128,16 @@ bool EditorController::textAreaDidReceiveEvent(TextArea * textArea, Ion::Events: return false; } +VariableBoxController * EditorController::variableBoxForInputEventHandler(InputEventHandler * textInput) { + VariableBoxController * varBox = static_cast(app())->variableBoxController(); + varBox->loadFunctionsAndVariables(); + return varBox; +} + +InputEventHandlerDelegateApp * EditorController::inputEventHandlerDelegateApp() { + return static_cast(app()); +} + StackViewController * EditorController::stackController() { return static_cast(parentResponder()); } diff --git a/apps/code/editor_controller.h b/apps/code/editor_controller.h index 807c3d003..3870b8bfa 100644 --- a/apps/code/editor_controller.h +++ b/apps/code/editor_controller.h @@ -4,13 +4,16 @@ #include #include "script.h" #include "editor_view.h" +#include "variable_box_controller.h" +#include "../shared/input_event_handler_delegate.h" namespace Code { class MenuController; class ScriptParameterController; +class App; -class EditorController : public ViewController, public TextAreaDelegate { +class EditorController : public ViewController, public TextAreaDelegate, public Shared::InputEventHandlerDelegate { public: EditorController(MenuController * menuController, App * pythonDelegate); void setScript(Script script); @@ -26,7 +29,11 @@ public: /* TextAreaDelegate */ bool textAreaDidReceiveEvent(TextArea * textArea, Ion::Events::Event event) override; + /* InputEventHandlerDelegate */ + VariableBoxController * variableBoxForInputEventHandler(InputEventHandler * textInput) override; + private: + Shared::InputEventHandlerDelegateApp * inputEventHandlerDelegateApp() override; static constexpr int k_indentationSpacesNumber = 2; StackViewController * stackController(); EditorView m_editorView; diff --git a/apps/code/variable_box_controller.cpp b/apps/code/variable_box_controller.cpp index 9d8c410ec..67c7ecbb4 100644 --- a/apps/code/variable_box_controller.cpp +++ b/apps/code/variable_box_controller.cpp @@ -47,32 +47,6 @@ static bool shouldAddObject(const char * name, int maxLength) { return true; } -void VariableBoxController::viewWillAppear() { - m_scriptNodesCount = 0; - m_scriptStore->scanScriptsForFunctionsAndVariables( - this, - [](void * context, const char * functionName, int scriptIndex) { - if (!shouldAddObject(functionName, k_maxScriptObjectNameSize)) { - return; - } - VariableBoxController * cvc = static_cast(context); - cvc->addFunctionAtIndex(functionName, scriptIndex);}, - [](void * context, const char * variableName, int scriptIndex) { - if (!shouldAddObject(variableName, k_maxScriptObjectNameSize)) { - return; - } - VariableBoxController * cvc = static_cast(context); - cvc->addVariableAtIndex(variableName, scriptIndex);}); - NestedMenuController::viewWillAppear(); -} - -void VariableBoxController::viewDidDisappear() { - for (int i = 0; i < k_maxScriptNodesCount; i++) { - m_scriptNodes[i] = ScriptNode(); - } - NestedMenuController::viewDidDisappear(); -} - int VariableBoxController::numberOfRows() { return m_scriptNodesCount < k_maxScriptNodesCount ? m_scriptNodesCount : k_maxScriptNodesCount; } @@ -91,6 +65,24 @@ int VariableBoxController::typeAtLocation(int i, int j) { return 0; } +void VariableBoxController::loadFunctionsAndVariables() { + m_scriptNodesCount = 0; + m_scriptStore->scanScriptsForFunctionsAndVariables( + this, + [](void * context, const char * functionName, int scriptIndex) { + if (!shouldAddObject(functionName, k_maxScriptObjectNameSize)) { + return; + } + VariableBoxController * cvc = static_cast(context); + cvc->addFunctionAtIndex(functionName, scriptIndex);}, + [](void * context, const char * variableName, int scriptIndex) { + if (!shouldAddObject(variableName, k_maxScriptObjectNameSize)) { + return; + } + VariableBoxController * cvc = static_cast(context); + cvc->addVariableAtIndex(variableName, scriptIndex);}); +} + HighlightCell * VariableBoxController::leafCellAtIndex(int index) { assert(index >= 0 && index < k_maxNumberOfDisplayedRows); return &m_leafCells[index]; diff --git a/apps/code/variable_box_controller.h b/apps/code/variable_box_controller.h index 6df4feb6f..046ad33bc 100644 --- a/apps/code/variable_box_controller.h +++ b/apps/code/variable_box_controller.h @@ -2,13 +2,14 @@ #define CODE_VARIABLE_BOX_CONTROLLER_H #include -#include "menu_controller.h" #include "script_node.h" #include "script_node_cell.h" #include "script_store.h" namespace Code { +class App; + class VariableBoxController : public NestedMenuController { public: VariableBoxController(App * pythonDelegate, ScriptStore * scriptStore); @@ -17,15 +18,14 @@ public: bool handleEvent(Ion::Events::Event event) override; void didEnterResponderChain(Responder * previousFirstResponder) override; - /* View Controller */ - void viewWillAppear() override; - void viewDidDisappear() override; - /* ListViewDataSource */ int numberOfRows() override; int reusableCellCount(int type) override; void willDisplayCellForIndex(HighlightCell * cell, int index) override; int typeAtLocation(int i, int j) override; + + /* VariableBoxController */ + void loadFunctionsAndVariables(); private: constexpr static int k_maxScriptObjectNameSize = 100; constexpr static int k_maxNumberOfDisplayedRows = 6; //240/40