[apps/code] The console marks imported script for the var box

After lauching the console, if we fetch a script we mark it as fetched.
When the variable box displays variables from imported scripts, it scans
all the variables from the scripts marked as fetched.
This commit is contained in:
Léa Saviot
2020-04-29 16:54:28 +02:00
committed by Émilie Feral
parent 9e973adbab
commit d1c8bbdaf7
13 changed files with 66 additions and 42 deletions

View File

@@ -61,7 +61,7 @@ void App::Snapshot::setOpt(const char * name, const char * value) {
const char * scriptContent = separator;
Code::ScriptTemplate script(scriptName, scriptContent);
m_scriptStore.addScriptFromTemplate(&script);
ScriptStore::ScriptNamed(scriptName).toggleImportationStatus(); // set Importation Status to 1
ScriptStore::ScriptNamed(scriptName).toggleAutoimportationStatus(); // set Importation Status to 1
return;
}
if (strcmp(name, "lock-on-console") == 0) {

View File

@@ -54,10 +54,13 @@ bool ConsoleController::loadPythonEnvironment() {
m_pythonDelegate->initPythonWithUser(this);
MicroPython::registerScriptProvider(m_scriptStore);
m_importScriptsWhenViewAppears = m_autoImportScripts;
#if 0
//TODO LEA
/* 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. */
App::app()->variableBoxController()->loadFunctionsAndVariables(-1, nullptr, -1);
#endif
return true;
}
@@ -65,6 +68,7 @@ void ConsoleController::unloadPythonEnvironment() {
if (!m_pythonDelegate->isPythonUser(nullptr)) {
m_consoleStore.startNewSession();
m_pythonDelegate->deinitPython();
m_scriptStore->clearFetchInformation();
}
}
@@ -474,7 +478,7 @@ void ConsoleController::autoImportScript(Script script, bool force) {
* the sandbox. */
hideAnyDisplayedViewController();
if (script.importationStatus() || force) {
if (script.autoImportationStatus() || force) {
// Step 1 - Create the command "from scriptName import *".
assert(strlen(k_importCommand1) + strlen(script.fullName()) - strlen(ScriptStore::k_scriptExtension) - 1 + strlen(k_importCommand2) + 1 <= k_maxImportCommandSize);

View File

@@ -37,7 +37,7 @@ void EditorController::setScript(Script script, int scriptIndex) {
* */
size_t newScriptSize = Ion::Storage::sharedStorage()->putAvailableSpaceAtEndOfRecord(m_script);
m_editorView.setText(const_cast<char *>(m_script.scriptContent()), newScriptSize - Script::k_importationStatusSize);
m_editorView.setText(const_cast<char *>(m_script.scriptContent()), newScriptSize - Script::InformationSize());
}
void EditorController::willExitApp() {
@@ -154,7 +154,7 @@ void EditorController::cleanStorageEmptySpace() {
Ion::Storage::Record::Data scriptValue = m_script.value();
Ion::Storage::sharedStorage()->getAvailableSpaceFromEndOfRecord(
m_script,
scriptValue.size - Script::k_importationStatusSize - (strlen(m_script.scriptContent()) + 1)); // TODO optimize number of script fetches
scriptValue.size - Script::InformationSize() - (strlen(m_script.scriptContent()) + 1)); // TODO optimize number of script fetches
}

View File

@@ -65,31 +65,35 @@ bool Script::nameCompliant(const char * name) {
return false;
}
bool Script::importationStatus() const {
bool Script::autoImportationStatus() const {
assert(!isNull());
Data d = value();
return (((char *)d.buffer)[0] == 1);
}
void Script::toggleImportationStatus() {
void Script::toggleAutoimportationStatus() {
assert(!isNull());
Data d = value();
((char *)d.buffer)[0] = (((char *)d.buffer)[0] == 1 ? 0 : 1);
setValue(d);
}
const char * Script::scriptContent() const {
assert(!isNull());
Data d = value();
return (const char *)d.buffer + k_autoimportationStatusSize + k_currentImportationStatusSize;
return ((const char *)d.buffer) + InformationSize();
}
bool Script::contentFetchedFromConsole() const {
assert(!isNull());
Data d = value();
return (((char *)d.buffer)[k_autoImportationStatusSize] == 1);
}
void Script::setContentFetchedFromConsole(bool fetch) const {
}
//TODO TODO LEA
void Script::setContentFetchedFromConsole(bool fetch) {
assert(!isNull());
Data d = value();
((char *)d.buffer)[k_autoImportationStatusSize] = fetch;
setValue(d);
}
}

View File

@@ -9,9 +9,14 @@ namespace Code {
* Script: | AutoImportationStatus | Content |*/
class Script : public Ion::Storage::Record {
public:
static constexpr size_t k_autoimportationStatusSize = 1;
private:
// Default script names are chosen between script1 and script99
static constexpr int k_maxNumberOfDefaultScriptNames = 99;
static constexpr int k_defaultScriptNameNumberMaxSize = 2; // Numbers from 1 to 99 have 2 digits max
static constexpr size_t k_autoImportationStatusSize = 1; //TODO LEA use only 1 byte for both status flags
static constexpr size_t k_currentImportationStatusSize = 1;
public:
static constexpr int k_defaultScriptNameMaxSize = 6 + k_defaultScriptNameNumberMaxSize + 1;
/* 6 = strlen("script")
* k_defaultScriptNameNumberMaxSize = maxLength of integers between 1 and 99
@@ -19,18 +24,14 @@ public:
static bool DefaultName(char buffer[], size_t bufferSize);
static bool nameCompliant(const char * name);
static constexpr size_t InformationSize() { return k_autoImportationStatusSize + k_currentImportationStatusSize; }
Script(Ion::Storage::Record r = Ion::Storage::Record()) : Record(r) {}
bool importationStatus() const;
void toggleImportationStatus();
bool autoImportationStatus() const;
void toggleAutoimportationStatus();
const char * scriptContent() const;
bool contentFetchedFromConsole() const;
void setContentFetchedFromConsole(bool fetch) const;
private:
// Default script names are chosen between script1 and script99
static constexpr int k_maxNumberOfDefaultScriptNames = 99;
static constexpr int k_defaultScriptNameNumberMaxSize = 2; // Numbers from 1 to 99 have 2 digits max
void setContentFetchedFromConsole(bool fetch);
};
}

View File

@@ -42,7 +42,7 @@ bool ScriptParameterController::handleEvent(Ion::Events::Event event) {
m_menuController->renameSelectedScript();
return true;
case 2:
m_script.toggleImportationStatus();
m_script.toggleAutoimportationStatus();
m_selectableTableView.reloadData();
m_menuController->reloadConsole();
Container::activeApp()->setFirstResponder(&m_selectableTableView);
@@ -81,7 +81,7 @@ HighlightCell * ScriptParameterController::reusableCell(int index) {
void ScriptParameterController::willDisplayCellForIndex(HighlightCell * cell, int index) {
if (cell == &m_autoImportScript) {
SwitchView * switchView = (SwitchView *)m_autoImportScript.accessoryView();
switchView->setState(m_script.importationStatus());
switchView->setState(m_script.autoImportationStatus());
}
}

View File

@@ -25,16 +25,27 @@ bool ScriptStore::isFull() {
return Ion::Storage::sharedStorage()->availableSize() < k_fullFreeSpaceSizeLimit;
}
const char * ScriptStore::contentOfScript(const char * name) {
const char * ScriptStore::contentOfScript(const char * name, bool markAsFetched) {
Script script = ScriptNamed(name);
if (script.isNull()) {
return nullptr;
}
if (markAsFetched) {
script.setContentFetchedFromConsole(true);
}
return script.scriptContent();
}
void ScriptStore::clearFetchInformation() {
// TODO optimize fetches
const int scriptsCount = numberOfScripts();
for (int i = 0; i < scriptsCount; i++) {
scriptAtIndex(i).setContentFetchedFromConsole(false);
}
}
Script::ErrorStatus ScriptStore::addScriptFromTemplate(const ScriptTemplate * scriptTemplate) {
size_t valueSize = strlen(scriptTemplate->content())+1+1;// scriptcontent size + 1 char for the importation status
size_t valueSize = Script::InformationSize() + strlen(scriptTemplate->content()) + 1; // (auto importation status + content fetched status) + scriptcontent size + null-terminating char
assert(Script::nameCompliant(scriptTemplate->name()));
Script::ErrorStatus err = Ion::Storage::sharedStorage()->createRecordWithFullName(scriptTemplate->name(), scriptTemplate->value(), valueSize);
assert(err != Script::ErrorStatus::NonCompliantName);

View File

@@ -39,7 +39,8 @@ public:
bool isFull();
/* MicroPython::ScriptProvider */
const char * contentOfScript(const char * name) override;
const char * contentOfScript(const char * name, bool markAsFetched) override;
void clearFetchInformation() override;
Ion::Storage::Record::ErrorStatus addScriptFromTemplate(const ScriptTemplate * scriptTemplate);
private:

View File

@@ -2,15 +2,15 @@
namespace Code {
constexpr ScriptTemplate emptyScriptTemplate(".py", "\x01" R"(from math import *
constexpr ScriptTemplate emptyScriptTemplate(".py", "\x01\x00" R"(from math import *
)");
constexpr ScriptTemplate squaresScriptTemplate("squares.py", "\x01" R"(
constexpr ScriptTemplate squaresScriptTemplate("squares.py", "\x01\x00" R"(
#from math import sin as stew, cos as cabbage
from math import *
)");
/*constexpr ScriptTemplate squaresScriptTemplate("squares.py", "\x01" R"(
/*constexpr ScriptTemplate squaresScriptTemplate("squares.py", "\x01\x00" R"(
import math
import math as m
import math, cmath
@@ -31,7 +31,7 @@ from math import sin as stew
from math import sin, cos
from math import sin as stew, cos as cabbage
*/
constexpr ScriptTemplate mandelbrotScriptTemplate("mandelbrot.py", "\x01" R"(# This script draws a Mandelbrot fractal set
constexpr ScriptTemplate mandelbrotScriptTemplate("mandelbrot.py", "\x01\x00" R"(# This script draws a Mandelbrot fractal set
# N_iteration: degree of precision
import kandinsky
def mandelbrot(N_iteration):
@@ -51,7 +51,7 @@ def mandelbrot(N_iteration):
# Draw a pixel colored in 'col' at position (x,y)
kandinsky.set_pixel(x,y,col))");
constexpr ScriptTemplate polynomialScriptTemplate("polynomial.py", "\x01" R"(from math import *
constexpr ScriptTemplate polynomialScriptTemplate("polynomial.py", "\x01\x00" R"(from math import *
# roots(a,b,c) computes the solutions of the equation a*x**2+b*x+c=0
def roots(a,b,c):
delta = b*b-4*a*c
@@ -64,7 +64,7 @@ def roots(a,b,c):
else:
return None)");
constexpr ScriptTemplate parabolaScriptTemplate("parabola.py", "\x01" R"(from matplotlib.pyplot import *
constexpr ScriptTemplate parabolaScriptTemplate("parabola.py", "\x01\x00" R"(from matplotlib.pyplot import *
from math import *
g=9.81

View File

@@ -1,6 +1,8 @@
#ifndef CODE_SCRIPT_TEMPLATE_H
#define CODE_SCRIPT_TEMPLATE_H
#include "script.h"
namespace Code {
class ScriptTemplate {
@@ -12,11 +14,11 @@ public:
static const ScriptTemplate * Polynomial();
static const ScriptTemplate * Parabola();
const char * name() const { return m_name; }
const char * content() const { return m_value+1; }
const char * content() const { return m_value + Script::InformationSize(); }
const char * value() const { return m_value; }
private:
const char * m_name;
const char * m_value; // hold the 'importation status' flag concatenate with the script content
const char * m_value; // holds the 'importation status' and 'current importation status' flags concatenated with the script content
};
}

View File

@@ -385,9 +385,9 @@ void VariableBoxController::insertTextInCaller(const char * text, int textLength
void VariableBoxController::loadVariablesImportedFromScripts() {
const int scriptsCount = m_scriptStore->numberOfScripts();
for (int i = 0; i < scriptsCount; i++) {
Script * script = m_scriptStore->scriptAtIndex(i);
if (script->contentFetchedFromConsole()) {
loadGlobalAndImportedVariablesInScriptAsImported(script->fullName(), script->scriptContent(), nullptr, -1, false);
Script script = m_scriptStore->scriptAtIndex(i);
if (script.contentFetchedFromConsole()) {
loadGlobalAndImportedVariablesInScriptAsImported(script.fullName(), script.scriptContent(), nullptr, -1, false); // TODO optimize number of script fetches
}
}
}

View File

@@ -288,7 +288,7 @@ void nlr_jump_fail(void *val) {
mp_lexer_t * mp_lexer_new_from_file(const char * filename) {
if (sScriptProvider != nullptr) {
const char * script = sScriptProvider->contentOfScript(filename);
const char * script = sScriptProvider->contentOfScript(filename, true);
if (script != nullptr) {
return mp_lexer_new_from_str_len(qstr_from_str(filename), script, strlen(script), 0 /* size_t free_len*/);
} else {
@@ -300,7 +300,7 @@ mp_lexer_t * mp_lexer_new_from_file(const char * filename) {
}
mp_import_stat_t mp_import_stat(const char *path) {
if (sScriptProvider && sScriptProvider->contentOfScript(path)) {
if (sScriptProvider && sScriptProvider->contentOfScript(path, false)) {
return MP_IMPORT_STAT_FILE;
}
return MP_IMPORT_STAT_NO_EXIST;

View File

@@ -12,7 +12,8 @@ namespace MicroPython {
class ScriptProvider {
public:
virtual const char * contentOfScript(const char * name) = 0;
virtual const char * contentOfScript(const char * name, bool markAsFetched) = 0;
virtual void clearFetchInformation() = 0;
};
class ExecutionEnvironment {