[code] Load Variable box content before compiling any other python code

to avoid memory exhaustion when displaying variable box
This commit is contained in:
Émilie Feral
2018-10-25 14:44:29 +02:00
parent c7e001a01d
commit a4f7d83805
7 changed files with 56 additions and 37 deletions

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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 *>(app())->variableBoxController()->loadFunctionsAndVariables();
m_sandboxIsDisplayed = false;
if (m_importScriptsWhenViewAppears) {
m_importScriptsWhenViewAppears = false;

View File

@@ -1,11 +1,12 @@
#include "editor_controller.h"
#include "menu_controller.h"
#include "script_parameter_controller.h"
#include "variable_box_controller.h"
#include <apps/code/app.h>
#include "app.h"
#include <escher/metric.h>
#include <ion.h>
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 *>(app())->variableBoxController();
varBox->loadFunctionsAndVariables();
return varBox;
}
InputEventHandlerDelegateApp * EditorController::inputEventHandlerDelegateApp() {
return static_cast<App *>(app());
}
StackViewController * EditorController::stackController() {
return static_cast<StackViewController *>(parentResponder());
}

View File

@@ -4,13 +4,16 @@
#include <escher.h>
#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;

View File

@@ -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<VariableBoxController *>(context);
cvc->addFunctionAtIndex(functionName, scriptIndex);},
[](void * context, const char * variableName, int scriptIndex) {
if (!shouldAddObject(variableName, k_maxScriptObjectNameSize)) {
return;
}
VariableBoxController * cvc = static_cast<VariableBoxController *>(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<VariableBoxController *>(context);
cvc->addFunctionAtIndex(functionName, scriptIndex);},
[](void * context, const char * variableName, int scriptIndex) {
if (!shouldAddObject(variableName, k_maxScriptObjectNameSize)) {
return;
}
VariableBoxController * cvc = static_cast<VariableBoxController *>(context);
cvc->addVariableAtIndex(variableName, scriptIndex);});
}
HighlightCell * VariableBoxController::leafCellAtIndex(int index) {
assert(index >= 0 && index < k_maxNumberOfDisplayedRows);
return &m_leafCells[index];

View File

@@ -2,13 +2,14 @@
#define CODE_VARIABLE_BOX_CONTROLLER_H
#include <escher.h>
#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