mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[apps/code] Fix script importation status
Scenario: Execute the script parabola.py, open the variable box, select any leaf, enter, open the variable box again -> no variables are loaded anymore
This commit is contained in:
@@ -52,7 +52,7 @@ bool ConsoleController::loadPythonEnvironment() {
|
|||||||
m_pythonDelegate->initPythonWithUser(this);
|
m_pythonDelegate->initPythonWithUser(this);
|
||||||
MicroPython::registerScriptProvider(m_scriptStore);
|
MicroPython::registerScriptProvider(m_scriptStore);
|
||||||
m_importScriptsWhenViewAppears = m_autoImportScripts;
|
m_importScriptsWhenViewAppears = m_autoImportScripts;
|
||||||
m_scriptStore->clearFetchInformation();
|
m_scriptStore->clearConsoleFetchInformation();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,16 +65,18 @@ bool Script::nameCompliant(const char * name) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t * StatusFromData(Script::Data d) {
|
||||||
|
return const_cast<uint8_t *>(static_cast<const uint8_t *>(d.buffer));
|
||||||
|
}
|
||||||
|
|
||||||
bool Script::autoImportationStatus() const {
|
bool Script::autoImportationStatus() const {
|
||||||
assert(!isNull());
|
return getStatutBit(k_autoImportationStatusMask);
|
||||||
Data d = value();
|
|
||||||
return (*statusFromData(d) & k_autoImportationStatusMask) == 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Script::toggleAutoimportationStatus() {
|
void Script::toggleAutoimportationStatus() {
|
||||||
assert(!isNull());
|
assert(!isNull());
|
||||||
Data d = value();
|
Data d = value();
|
||||||
*statusFromData(d) ^= k_autoImportationStatusMask;
|
*StatusFromData(d) ^= k_autoImportationStatusMask;
|
||||||
setValue(d);
|
setValue(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,46 +85,34 @@ const char * Script::content() const {
|
|||||||
return ((const char *)d.buffer) + StatusSize();
|
return ((const char *)d.buffer) + StatusSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Script::contentFetchedFromConsole() const {
|
bool Script::fetchedFromConsole() const {
|
||||||
return fetchedStatus() == FetchedStatus::FromConsole;
|
return getStatutBit(k_fetchedFromConsoleMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Script::contentFetchedForVariableBox() const {
|
void Script::setFetchedFromConsole(bool fetched) {
|
||||||
return fetchedStatus() == FetchedStatus::ForVariableBox;
|
setStatutBit(k_fetchedFromConsoleMask, k_fetchedFromConsoleOffset, fetched);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Script::setContentFetchedFromConsole() {
|
bool Script::fetchedForVariableBox() const {
|
||||||
setFetchedStatus(FetchedStatus::FromConsole);
|
return getStatutBit(k_fetchedForVariableBoxMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Script::setContentFetchedForVariableBox() {
|
void Script::setFetchedForVariableBox(bool fetched) {
|
||||||
setFetchedStatus(FetchedStatus::ForVariableBox);
|
setStatutBit(k_fetchedForVariableBoxMask, k_fetchedForVariableBoxOffset, fetched);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Script::resetContentFetchedStatus() {
|
bool Script::getStatutBit(uint8_t mask) const {
|
||||||
setFetchedStatus(FetchedStatus::None);
|
|
||||||
}
|
|
||||||
|
|
||||||
Script::FetchedStatus Script::fetchedStatus() const {
|
|
||||||
assert(!isNull());
|
assert(!isNull());
|
||||||
Data d = value();
|
Data d = value();
|
||||||
uint8_t status = (*statusFromData(d)) >> k_fetchedStatusOffset;
|
return ((*StatusFromData(d)) & mask) != 0;
|
||||||
assert(status == static_cast<uint8_t>(FetchedStatus::None)
|
|
||||||
|| status == static_cast<uint8_t>(FetchedStatus::FromConsole)
|
|
||||||
|| status == static_cast<uint8_t>(FetchedStatus::ForVariableBox));
|
|
||||||
return static_cast<FetchedStatus>(status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Script::setFetchedStatus(FetchedStatus fetchedStatus) {
|
void Script::setStatutBit(uint8_t mask, uint8_t offset, bool statusBit) {
|
||||||
assert(!isNull());
|
assert(!isNull());
|
||||||
Data d = value();
|
Data d = value();
|
||||||
uint8_t * status = statusFromData(d);
|
uint8_t * status = StatusFromData(d);
|
||||||
*status = ((*status) & ~k_fetchedStatusMask) | (static_cast<uint8_t>(fetchedStatus) << k_fetchedStatusOffset); //TODO Create and use a bit operations library
|
*status = ((*status) & ~mask) | (static_cast<uint8_t>(statusBit) << offset); //TODO Create and use a bit operations library
|
||||||
setValue(d);
|
setValue(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t * Script::statusFromData(Data d) const {
|
|
||||||
return const_cast<uint8_t *>(static_cast<const uint8_t *>(d.buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,22 +8,22 @@ namespace Code {
|
|||||||
/* Record: | Size | Name | Body |
|
/* Record: | Size | Name | Body |
|
||||||
* Script: | | | Status | Content |
|
* Script: | | | Status | Content |
|
||||||
*
|
*
|
||||||
* Status is a byte long: xxxxxxxx
|
|
||||||
* ^^ ^
|
|
||||||
* FetchedStatus AutoImportationStatus
|
|
||||||
*
|
*
|
||||||
* AutoImportationStatus is 1 if the script should be auto imported when the
|
* |FetchedForVariableBoxBit
|
||||||
|
* Status is one byte long: xxxxxxxx
|
||||||
|
* ^ ^
|
||||||
|
* FetchedFromConsoleBit AutoImportationBit
|
||||||
|
*
|
||||||
|
* AutoImportationBit is 1 if the script should be auto imported when the
|
||||||
* console opens.
|
* console opens.
|
||||||
*
|
*
|
||||||
* FetchedStatus has two purposes:
|
* FetchedFromConsoleBit is 1 if its content has been fetched from the console,
|
||||||
* - It is used to detect which scripts are imported in the console, so we can
|
* so we can retrieve the correct variables afterwards in the variable box.
|
||||||
* retrieve the correct variables afterwards in the variable box. When a
|
*
|
||||||
* script has been imported, its fetchedStatus value is
|
* FetchedForVariableBoxBit is used to prevent circular importation problems,
|
||||||
* FetchedStatus::FromConsole.
|
* such as scriptA importing scriptB, which imports scriptA. Once we get the
|
||||||
* - It is used to prevent circular importation problems, such as scriptA
|
* variables from a script to put them in the variable box, we switch the bit to
|
||||||
* importing scriptB, which imports scriptA. Once we get the variables from a
|
* 1 and won't reload it afterwards. */
|
||||||
* script to put them in the variable box, we switch the status to
|
|
||||||
* FetchedStatus::ForVariableBox and won't reload it afterwards. */
|
|
||||||
|
|
||||||
class Script : public Ion::Storage::Record {
|
class Script : public Ion::Storage::Record {
|
||||||
private:
|
private:
|
||||||
@@ -49,25 +49,22 @@ public:
|
|||||||
bool autoImportationStatus() const;
|
bool autoImportationStatus() const;
|
||||||
void toggleAutoimportationStatus();
|
void toggleAutoimportationStatus();
|
||||||
const char * content() const;
|
const char * content() const;
|
||||||
bool contentFetchedFromConsole() const;
|
|
||||||
bool contentFetchedForVariableBox() const;
|
/* Fetched status */
|
||||||
void setContentFetchedFromConsole();
|
bool fetchedFromConsole() const;
|
||||||
void setContentFetchedForVariableBox();
|
void setFetchedFromConsole(bool fetched);
|
||||||
void resetContentFetchedStatus();
|
bool fetchedForVariableBox() const;
|
||||||
|
void setFetchedForVariableBox(bool fetched);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr uint8_t k_autoImportationStatusMask = 0b1;
|
static constexpr uint8_t k_autoImportationStatusMask = 0b1;
|
||||||
static constexpr uint8_t k_fetchedStatusBits = 0b11;
|
static constexpr uint8_t k_fetchedForVariableBoxOffset = 7;
|
||||||
static constexpr uint8_t k_fetchedStatusOffset = 6;
|
static constexpr uint8_t k_fetchedFromConsoleOffset = 6;
|
||||||
static constexpr uint8_t k_fetchedStatusMask = k_fetchedStatusBits << k_fetchedStatusOffset;
|
static constexpr uint8_t k_fetchedForVariableBoxMask = 0b1 << k_fetchedForVariableBoxOffset;
|
||||||
/* Fetched status */
|
static constexpr uint8_t k_fetchedFromConsoleMask = 0b1 << k_fetchedFromConsoleOffset;
|
||||||
enum class FetchedStatus : uint8_t {
|
|
||||||
None = 0,
|
bool getStatutBit(uint8_t offset) const;
|
||||||
FromConsole = 1,
|
void setStatutBit(uint8_t mask, uint8_t offset, bool value);
|
||||||
ForVariableBox = 2
|
|
||||||
};
|
|
||||||
FetchedStatus fetchedStatus() const;
|
|
||||||
void setFetchedStatus(FetchedStatus status);
|
|
||||||
uint8_t * statusFromData(Data d) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,16 +31,24 @@ const char * ScriptStore::contentOfScript(const char * name, bool markAsFetched)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (markAsFetched) {
|
if (markAsFetched) {
|
||||||
script.setContentFetchedFromConsole();
|
script.setFetchedFromConsole(true);
|
||||||
}
|
}
|
||||||
return script.content();
|
return script.content();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptStore::clearFetchInformation() {
|
void ScriptStore::clearVariableBoxFetchInformation() {
|
||||||
// TODO optimize fetches
|
// TODO optimize fetches
|
||||||
const int scriptsCount = numberOfScripts();
|
const int scriptsCount = numberOfScripts();
|
||||||
for (int i = 0; i < scriptsCount; i++) {
|
for (int i = 0; i < scriptsCount; i++) {
|
||||||
scriptAtIndex(i).resetContentFetchedStatus();
|
scriptAtIndex(i).setFetchedForVariableBox(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptStore::clearConsoleFetchInformation() {
|
||||||
|
// TODO optimize fetches
|
||||||
|
const int scriptsCount = numberOfScripts();
|
||||||
|
for (int i = 0; i < scriptsCount; i++) {
|
||||||
|
scriptAtIndex(i).setFetchedFromConsole(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ public:
|
|||||||
|
|
||||||
/* MicroPython::ScriptProvider */
|
/* MicroPython::ScriptProvider */
|
||||||
const char * contentOfScript(const char * name, bool markAsFetched) override;
|
const char * contentOfScript(const char * name, bool markAsFetched) override;
|
||||||
void clearFetchInformation() override;
|
void clearVariableBoxFetchInformation();
|
||||||
|
void clearConsoleFetchInformation();
|
||||||
|
|
||||||
Ion::Storage::Record::ErrorStatus addScriptFromTemplate(const ScriptTemplate * scriptTemplate);
|
Ion::Storage::Record::ErrorStatus addScriptFromTemplate(const ScriptTemplate * scriptTemplate);
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ void VariableBoxController::loadFunctionsAndVariables(int scriptIndex, const cha
|
|||||||
|
|
||||||
// Reset the node counts
|
// Reset the node counts
|
||||||
empty();
|
empty();
|
||||||
m_scriptStore->clearFetchInformation();
|
|
||||||
if (textToAutocomplete != nullptr && textToAutocompleteLength < 0) {
|
if (textToAutocomplete != nullptr && textToAutocompleteLength < 0) {
|
||||||
textToAutocompleteLength = strlen(textToAutocomplete);
|
textToAutocompleteLength = strlen(textToAutocomplete);
|
||||||
}
|
}
|
||||||
@@ -180,8 +180,8 @@ void VariableBoxController::loadFunctionsAndVariables(int scriptIndex, const cha
|
|||||||
/* Handle the FetchedStatus: we will import the current script variables in
|
/* Handle the FetchedStatus: we will import the current script variables in
|
||||||
* loadCurrentVariablesInScript, so we do not want to import those variables
|
* loadCurrentVariablesInScript, so we do not want to import those variables
|
||||||
* before, if any imported script also imported the current script. */
|
* before, if any imported script also imported the current script. */
|
||||||
assert(!script.contentFetchedFromConsole() && !script.contentFetchedForVariableBox());
|
assert(!script.fetchedFromConsole() && !script.fetchedForVariableBox());
|
||||||
script.setContentFetchedForVariableBox();
|
script.setFetchedForVariableBox(true);
|
||||||
|
|
||||||
// Load the imported and current variables
|
// Load the imported and current variables
|
||||||
const char * scriptContent = script.content();
|
const char * scriptContent = script.content();
|
||||||
@@ -229,7 +229,7 @@ void VariableBoxController::loadVariablesImportedFromScripts() {
|
|||||||
const int scriptsCount = m_scriptStore->numberOfScripts();
|
const int scriptsCount = m_scriptStore->numberOfScripts();
|
||||||
for (int i = 0; i < scriptsCount; i++) {
|
for (int i = 0; i < scriptsCount; i++) {
|
||||||
Script script = m_scriptStore->scriptAtIndex(i);
|
Script script = m_scriptStore->scriptAtIndex(i);
|
||||||
if (script.contentFetchedFromConsole()) {
|
if (script.fetchedFromConsole()) {
|
||||||
loadGlobalAndImportedVariablesInScriptAsImported(script, nullptr, -1, false);
|
loadGlobalAndImportedVariablesInScriptAsImported(script, nullptr, -1, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,6 +240,7 @@ void VariableBoxController::empty() {
|
|||||||
m_currentScriptNodesCount = 0;
|
m_currentScriptNodesCount = 0;
|
||||||
m_importedNodesCount = 0;
|
m_importedNodesCount = 0;
|
||||||
m_shortenResultCharCount = 0;
|
m_shortenResultCharCount = 0;
|
||||||
|
m_scriptStore->clearVariableBoxFetchInformation();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VariableBoxController::insertAutocompletionResultAtIndex(int index) {
|
void VariableBoxController::insertAutocompletionResultAtIndex(int index) {
|
||||||
@@ -628,7 +629,7 @@ void VariableBoxController::loadCurrentVariablesInScript(const char * scriptCont
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VariableBoxController::loadGlobalAndImportedVariablesInScriptAsImported(Script script, const char * textToAutocomplete, int textToAutocompleteLength, bool importFromModules) {
|
void VariableBoxController::loadGlobalAndImportedVariablesInScriptAsImported(Script script, const char * textToAutocomplete, int textToAutocompleteLength, bool importFromModules) {
|
||||||
if (script.contentFetchedForVariableBox()) {
|
if (script.fetchedForVariableBox()) {
|
||||||
// We already fetched these script variables
|
// We already fetched these script variables
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -674,7 +675,7 @@ void VariableBoxController::loadGlobalAndImportedVariablesInScriptAsImported(Scr
|
|||||||
nlr_pop();
|
nlr_pop();
|
||||||
}
|
}
|
||||||
// Mark that we already fetched these script variables
|
// Mark that we already fetched these script variables
|
||||||
script.setContentFetchedForVariableBox();
|
script.setFetchedForVariableBox(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VariableBoxController::addNodesFromImportMaybe(mp_parse_node_struct_t * parseNode, const char * textToAutocomplete, int textToAutocompleteLength, bool importFromModules) {
|
bool VariableBoxController::addNodesFromImportMaybe(mp_parse_node_struct_t * parseNode, const char * textToAutocomplete, int textToAutocompleteLength, bool importFromModules) {
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ namespace MicroPython {
|
|||||||
class ScriptProvider {
|
class ScriptProvider {
|
||||||
public:
|
public:
|
||||||
virtual const char * contentOfScript(const char * name, bool markAsFetched) = 0;
|
virtual const char * contentOfScript(const char * name, bool markAsFetched) = 0;
|
||||||
virtual void clearFetchInformation() = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExecutionEnvironment {
|
class ExecutionEnvironment {
|
||||||
|
|||||||
Reference in New Issue
Block a user