[apps/code] Status at the beginning of a script is one byte long

This saves space + avoids clashes with the NumWorks Workshop when
exchanging scripts
This commit is contained in:
Léa Saviot
2020-06-05 11:28:12 +02:00
parent d53a16eb91
commit 9a1ff2bd33
6 changed files with 33 additions and 20 deletions

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.content()), newScriptSize - Script::InformationSize());
m_editorView.setText(const_cast<char *>(m_script.content()), newScriptSize - Script::StatusSize());
}
void EditorController::willExitApp() {
@@ -156,7 +156,7 @@ void EditorController::cleanStorageEmptySpace() {
Ion::Storage::Record::Data scriptValue = m_script.value();
Ion::Storage::sharedStorage()->getAvailableSpaceFromEndOfRecord(
m_script,
scriptValue.size - Script::InformationSize() - (strlen(m_script.content()) + 1)); // TODO optimize number of script fetches
scriptValue.size - Script::StatusSize() - (strlen(m_script.content()) + 1)); // TODO optimize number of script fetches
}

View File

@@ -68,19 +68,19 @@ bool Script::nameCompliant(const char * name) {
bool Script::autoImportationStatus() const {
assert(!isNull());
Data d = value();
return (((char *)d.buffer)[0] == 1);
return (*statusFromData(d) & k_autoImportationStatusMask) == 1;
}
void Script::toggleAutoimportationStatus() {
assert(!isNull());
Data d = value();
((char *)d.buffer)[0] = (((char *)d.buffer)[0] == 1 ? 0 : 1);
*statusFromData(d) ^= k_autoImportationStatusMask;
setValue(d);
}
const char * Script::content() const {
Data d = value();
return ((const char *)d.buffer) + InformationSize();
return ((const char *)d.buffer) + StatusSize();
}
bool Script::contentFetchedFromConsole() const {
@@ -106,19 +106,23 @@ void Script::resetContentFetchedStatus() {
Script::FetchedStatus Script::fetchedStatus() const {
assert(!isNull());
Data d = value();
uint8_t status = const_cast<uint8_t *>(static_cast<const uint8_t *>(d.buffer))[k_autoImportationStatusSize];
uint8_t status = (*statusFromData(d)) >> k_fetchedStatusOffset;
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 status) {
void Script::setFetchedStatus(FetchedStatus fetchedStatus) {
assert(!isNull());
Data d = value();
const_cast<uint8_t *>(static_cast<const uint8_t *>(d.buffer))[k_autoImportationStatusSize] = static_cast<uint8_t>(status);
uint8_t * status = statusFromData(d);
*status = ((*status) & ~k_fetchedStatusMask) | (static_cast<uint8_t>(fetchedStatus) << k_fetchedStatusOffset); //TODO Create and use a bit operations library
setValue(d);
}
uint8_t * Script::statusFromData(Data d) const {
return const_cast<uint8_t *>(static_cast<const uint8_t *>(d.buffer));
}
}

View File

@@ -5,8 +5,12 @@
namespace Code {
/* Record: | Size | Name | Body |
* Script: | | | AutoImportationStatus | FetchedStatus | Content |
/* Record: | Size | Name | Body |
* Script: | | | Status | Content |
*
* Status is a byte long: xxxxxxxx
* ^^ ^
* FetchedStatus AutoImportationStatus
*
* AutoImportationStatus is 1 if the script should be auto imported when the
* console opens.
@@ -27,8 +31,8 @@ private:
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 use only 1 byte for both status flags
static constexpr size_t k_currentImportationStatusSize = 1;
// See the comment at the beginning of the file
static constexpr size_t k_statusSize = 1;
public:
static constexpr int k_defaultScriptNameMaxSize = 6 + k_defaultScriptNameNumberMaxSize + 1;
@@ -38,7 +42,7 @@ 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; }
static constexpr size_t StatusSize() { return k_statusSize; }
Script(Ion::Storage::Record r = Ion::Storage::Record()) : Record(r) {}
@@ -51,6 +55,10 @@ public:
void setContentFetchedForVariableBox();
void resetContentFetchedStatus();
private:
static constexpr uint8_t k_autoImportationStatusMask = 0b1;
static constexpr uint8_t k_fetchedStatusBits = 0b11;
static constexpr uint8_t k_fetchedStatusOffset = 6;
static constexpr uint8_t k_fetchedStatusMask = k_fetchedStatusBits << k_fetchedStatusOffset;
/* Fetched status */
enum class FetchedStatus : uint8_t {
None = 0,
@@ -59,6 +67,7 @@ private:
};
FetchedStatus fetchedStatus() const;
void setFetchedStatus(FetchedStatus status);
uint8_t * statusFromData(Data d) const;
};
}

View File

@@ -45,7 +45,7 @@ void ScriptStore::clearFetchInformation() {
}
Script::ErrorStatus ScriptStore::addScriptFromTemplate(const ScriptTemplate * scriptTemplate) {
size_t valueSize = Script::InformationSize() + strlen(scriptTemplate->content()) + 1; // (auto importation status + content fetched status) + scriptcontent size + null-terminating char
size_t valueSize = Script::StatusSize() + 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

@@ -2,10 +2,10 @@
namespace Code {
constexpr ScriptTemplate emptyScriptTemplate(".py", "\x01\x00" R"(from math import *
constexpr ScriptTemplate emptyScriptTemplate(".py", "\x01" R"(from math import *
)");
constexpr ScriptTemplate squaresScriptTemplate("squares.py", "\x01\x00" R"(from math import *
constexpr ScriptTemplate squaresScriptTemplate("squares.py", "\x01" R"(from math import *
from turtle import *
def squares(angle=0.5):
reset()
@@ -20,7 +20,7 @@ def squares(angle=0.5):
L=L-L*sin(angle*pi/180)
hideturtle())");
constexpr ScriptTemplate mandelbrotScriptTemplate("mandelbrot.py", "\x01\x00" R"(# This script draws a Mandelbrot fractal set
constexpr ScriptTemplate mandelbrotScriptTemplate("mandelbrot.py", "\x01" R"(# This script draws a Mandelbrot fractal set
# N_iteration: degree of precision
import kandinsky
def mandelbrot(N_iteration):
@@ -40,7 +40,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\x00" R"(from math import *
constexpr ScriptTemplate polynomialScriptTemplate("polynomial.py", "\x01" 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
@@ -53,7 +53,7 @@ def roots(a,b,c):
else:
return None)");
constexpr ScriptTemplate parabolaScriptTemplate("parabola.py", "\x01\x00" R"(from matplotlib.pyplot import *
constexpr ScriptTemplate parabolaScriptTemplate("parabola.py", "\x01" R"(from matplotlib.pyplot import *
from math import *
g=9.81

View File

@@ -14,7 +14,7 @@ public:
static const ScriptTemplate * Polynomial();
static const ScriptTemplate * Parabola();
const char * name() const { return m_name; }
const char * content() const { return m_value + Script::InformationSize(); }
const char * content() const { return m_value + Script::StatusSize(); }
const char * value() const { return m_value; }
private:
const char * m_name;