mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[ion] Ion::Storage is not a global variable anymore
This commit is contained in:
@@ -4,8 +4,7 @@
|
||||
#include "variable_box_controller.h"
|
||||
#include <apps/code/app.h>
|
||||
#include <escher/metric.h>
|
||||
|
||||
extern Ion::Storage storage;
|
||||
#include <ion.h>
|
||||
|
||||
namespace Code {
|
||||
|
||||
@@ -28,7 +27,7 @@ void EditorController::setScript(Script script) {
|
||||
m_script = script;
|
||||
const char * scriptBody = m_script.readContent();
|
||||
size_t scriptBodySize = strlen(scriptBody)+1;
|
||||
size_t availableScriptSize = scriptBodySize + storage.availableSize();
|
||||
size_t availableScriptSize = scriptBodySize + Ion::Storage::sharedStorage()->availableSize();
|
||||
assert(m_areaBuffer == nullptr);
|
||||
m_areaBuffer = new char[availableScriptSize];
|
||||
strlcpy(m_areaBuffer, scriptBody, scriptBodySize);
|
||||
|
||||
@@ -26,7 +26,7 @@ void ScriptStore::deleteAllScripts() {
|
||||
}
|
||||
|
||||
bool ScriptStore::isFull() {
|
||||
return (numberOfScripts() >= k_maxNumberOfScripts || storage.availableSize() < k_fullFreeSpaceSizeLimit);
|
||||
return (numberOfScripts() >= k_maxNumberOfScripts || Ion::Storage::sharedStorage()->availableSize() < k_fullFreeSpaceSizeLimit);
|
||||
}
|
||||
|
||||
void ScriptStore::scanScriptsForFunctionsAndVariables(void * context, ScanCallback storeFunction, ScanCallback storeVariable) {
|
||||
@@ -124,7 +124,7 @@ Script::ErrorStatus ScriptStore::addScriptFromTemplate(const ScriptTemplate * sc
|
||||
char * body = new char[scriptSize+Script::k_importationStatusSize];
|
||||
body[0] = 1;
|
||||
strlcpy(body+Script::k_importationStatusSize, scriptTemplate->content(), scriptSize);
|
||||
Script::ErrorStatus err = storage.createRecord(scriptTemplate->name(), body, scriptSize+Script::k_importationStatusSize);
|
||||
Script::ErrorStatus err = Ion::Storage::sharedStorage()->createRecord(scriptTemplate->name(), body, scriptSize+Script::k_importationStatusSize);
|
||||
assert(err != Script::ErrorStatus::NonCompliantName);
|
||||
delete[] body;
|
||||
return err;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef CODE_SCRIPT_STORE_H
|
||||
#define CODE_SCRIPT_STORE_H
|
||||
|
||||
#include <ion.h>
|
||||
#include "script.h"
|
||||
#include "script_template.h"
|
||||
#include <python/port/port.h>
|
||||
@@ -8,8 +9,6 @@ extern "C" {
|
||||
#include "py/parse.h"
|
||||
}
|
||||
|
||||
extern Ion::Storage storage;
|
||||
|
||||
namespace Code {
|
||||
|
||||
class ScriptStore : public MicroPython::ScriptProvider {
|
||||
@@ -20,13 +19,13 @@ public:
|
||||
|
||||
ScriptStore();
|
||||
Script scriptAtIndex(int index) {
|
||||
return Script(storage.recordWithExtensionAtIndex(k_scriptExtension, index));
|
||||
return Script(Ion::Storage::sharedStorage()->recordWithExtensionAtIndex(k_scriptExtension, index));
|
||||
}
|
||||
Script scriptNamed(const char * name) {
|
||||
return Script(storage.recordNamed(name));
|
||||
return Script(Ion::Storage::sharedStorage()->recordNamed(name));
|
||||
}
|
||||
int numberOfScripts() {
|
||||
return storage.numberOfRecordsWithExtension(k_scriptExtension);
|
||||
return Ion::Storage::sharedStorage()->numberOfRecordsWithExtension(k_scriptExtension);
|
||||
}
|
||||
Ion::Storage::Record::ErrorStatus addNewScript() {
|
||||
return addScriptFromTemplate(ScriptTemplate::Empty());
|
||||
|
||||
@@ -5,19 +5,12 @@
|
||||
|
||||
namespace Ion {
|
||||
|
||||
class Storage;
|
||||
|
||||
}
|
||||
|
||||
extern Ion::Storage storage;
|
||||
|
||||
namespace Ion {
|
||||
|
||||
/* Storage : | Magic | Record1 | Record2 | ... | Magic |
|
||||
* | Magic | Size1(uint16_t) | Name1 | Body1 | Size2(uint16_t) | Name2 | Body2 | ... | Magic */
|
||||
|
||||
class Storage {
|
||||
public:
|
||||
static Storage * sharedStorage();
|
||||
class Record {
|
||||
/* A Record is identified by the CRC32 on his name because:
|
||||
* - a record is identified by its name which is unique
|
||||
@@ -46,19 +39,19 @@ public:
|
||||
return m_nameCRC32 == 0;
|
||||
}
|
||||
const char * name() const {
|
||||
return storage.nameOfRecord(*this);
|
||||
return Storage::sharedStorage()->nameOfRecord(*this);
|
||||
}
|
||||
ErrorStatus setName(const char * name) {
|
||||
return storage.setNameOfRecord(*this, name);
|
||||
return Storage::sharedStorage()->setNameOfRecord(*this, name);
|
||||
}
|
||||
Data value() const {
|
||||
return storage.valueOfRecord(*this);
|
||||
return Storage::sharedStorage()->valueOfRecord(*this);
|
||||
}
|
||||
ErrorStatus setValue(Data data) {
|
||||
return storage.setValueOfRecord(*this, data);
|
||||
return Storage::sharedStorage()->setValueOfRecord(*this, data);
|
||||
}
|
||||
void destroy() {
|
||||
return storage.destroyRecord(*this);
|
||||
return Storage::sharedStorage()->destroyRecord(*this);
|
||||
}
|
||||
private:
|
||||
uint32_t m_nameCRC32;
|
||||
|
||||
@@ -13,7 +13,10 @@
|
||||
#define HEADER_SECTION
|
||||
#endif
|
||||
|
||||
extern Ion::Storage storage;
|
||||
namespace Ion {
|
||||
extern char staticStorageArea[];
|
||||
}
|
||||
constexpr void * storageAddress = &(Ion::staticStorageArea);
|
||||
|
||||
class PlatformInfo {
|
||||
public:
|
||||
@@ -21,7 +24,7 @@ public:
|
||||
m_header(Magic),
|
||||
m_version{EPSILON_VERSION},
|
||||
m_patchLevel{PATCH_LEVEL},
|
||||
m_storageAddress(&storage),
|
||||
m_storageAddress(storageAddress),
|
||||
m_footer(Magic) { }
|
||||
const char * version() const {
|
||||
assert(m_storageAddress != nullptr);
|
||||
|
||||
@@ -1,11 +1,31 @@
|
||||
#include <ion.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
Ion::Storage storage;
|
||||
#include <new>
|
||||
|
||||
namespace Ion {
|
||||
|
||||
/* We want to implement a simple singleton pattern, to make sure the storage is
|
||||
* initialized on first use, therefore preventing the static init order fiasco.
|
||||
* That being said, we rely on knowing where the storage resides in the device's
|
||||
* memory at compile time. Indeed, we want to advertise the static storage's
|
||||
* memory address in the PlatformInfo structure (so that we can read and write
|
||||
* it in DFU).
|
||||
* Using a "static Storage storage;" variable makes it a local symbol at best,
|
||||
* preventing the PlatformInfo from retrieving its address. And making the
|
||||
* Storage variable global yields the static init fiasco issue. We're working
|
||||
* around both issues by creating a global staticStorageArea buffer, and by
|
||||
* placement-newing the Storage into that area on first use. */
|
||||
|
||||
char staticStorageArea[sizeof(Storage)] = {0};
|
||||
Storage * Storage::sharedStorage() {
|
||||
static Storage * storage = nullptr;
|
||||
if (storage == nullptr) {
|
||||
storage = new (staticStorageArea) Storage();
|
||||
}
|
||||
return storage;
|
||||
}
|
||||
|
||||
Storage::Record::Record(const char * name) {
|
||||
if (name == nullptr) {
|
||||
m_nameCRC32 = 0;
|
||||
|
||||
Reference in New Issue
Block a user