Skip to content

Commit

Permalink
Merge pull request #302 from Genio-The-Haiku-IDE/feature/config-on-at…
Browse files Browse the repository at this point in the history
…tribute

Feature/config on attribute
  • Loading branch information
jackburton79 authored Jan 30, 2024
2 parents e61b408 + ad742f1 commit 6780eb5
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 51 deletions.
195 changes: 155 additions & 40 deletions src/config/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,123 @@

#include "Log.h"

class PermanentStorageProvider {
public:
enum kPSPMode { kPSPReadMode, kPSPWriteMode };

PermanentStorageProvider(BPath destination, kPSPMode mode) {};

virtual status_t InitCheck() = 0;
virtual status_t LoadKey(ConfigManager& manager, const char* key, GMessage& storage, GMessage& parConfig) = 0;
virtual status_t SaveKey(ConfigManager& manager, const char* key, GMessage& storage) = 0;

};

class BMessagePSP : public PermanentStorageProvider {
public:
BMessagePSP(BPath dest, kPSPMode mode): PermanentStorageProvider(dest, mode){
status = file.SetTo(dest.Path(), mode == PermanentStorageProvider::kPSPReadMode ? B_READ_ONLY : (B_WRITE_ONLY | B_CREATE_FILE));
if (status == B_OK && file.IsReadable()) {
status = fromFile.Unflatten(&file);
}
}
~BMessagePSP() {
if (status == B_OK && file.IsWritable()) {
fromFile.Flatten(&file);
file.Flush();
}
}

status_t InitCheck() {
return status;
}

status_t LoadKey(ConfigManager& manager, const char* key, GMessage& storage, GMessage& paramerConfig) {
if (fromFile.Has(key) && _SameTypeAndFixedSize(&fromFile, key, &storage, key)) {
manager[key] = fromFile[key];
return B_OK;
}
return B_NAME_NOT_FOUND;
}
status_t SaveKey(ConfigManager& manager, const char* key, GMessage& storage) {
fromFile[key] = storage[key];
return B_OK;
}

private:
BFile file;
GMessage fromFile;
status_t status = B_ERROR;

bool _SameTypeAndFixedSize(
BMessage* msgL, const char* keyL, BMessage* msgR, const char* keyR) const
{
type_code typeL = 0;
bool fixedSizeL = false;
if (msgL->GetInfo(keyL, &typeL, &fixedSizeL) == B_OK) {
type_code typeR = 0;
bool fixedSizeR = false;
if (msgR->GetInfo(keyR, &typeR, &fixedSizeR) == B_OK) {
return (typeL == typeR && fixedSizeL == fixedSizeR);
}
}
return false;
}
};

class AttributePSP : public PermanentStorageProvider {
public:
AttributePSP(BPath attributeFilePath, kPSPMode mode): PermanentStorageProvider(attributeFilePath, mode){
status = nodeAttr.SetTo(attributeFilePath.Path());
}

status_t InitCheck() { return status; }
status_t LoadKey(ConfigManager& manager, const char* key, GMessage& storage, GMessage& paramerConfig)
{
BString attrName("genio:");
attrName.Append(key);
const void* data = nullptr;
ssize_t numBytes = 0;
type_code type = paramerConfig.Type("default_value");
if (paramerConfig.FindData("default_value", type, &data, &numBytes) == B_OK) {
void* buffer = malloc(numBytes);
ssize_t readStatus = nodeAttr.ReadAttr(attrName.String(), type, 0, buffer, numBytes);
if (readStatus <=0)
return B_NAME_NOT_FOUND;

storage.RemoveName(key);
status_t st = storage.AddData(key, type, buffer, numBytes);
if (st == B_OK) {
GMessage noticeMessage(manager.UpdateMessageWhat());
noticeMessage["key"] = key;
noticeMessage["value"] = storage[key];
if (be_app != nullptr)
be_app->SendNotices(manager.UpdateMessageWhat(), &noticeMessage);
}
free(buffer);
return st;
}
return B_NAME_NOT_FOUND;
}
status_t SaveKey(ConfigManager& manager, const char* key, GMessage& storage) {
// save as attribute:
BString attrName("genio:");
attrName.Append(key);
const void* data = nullptr;
ssize_t numBytes = 0;
type_code type = storage.Type(key);
if (storage.FindData(key, type, &data, &numBytes) == B_OK) {
if (nodeAttr.WriteAttr(attrName.String(), type, 0, data, numBytes) <= 0) {
return B_ERROR;
}
}
return B_OK;
}
private:
BNode nodeAttr;
status_t status = B_ERROR;
};


ConfigManager::ConfigManager(const int32 messageWhat)
:
Expand All @@ -39,38 +156,53 @@ ConfigManager::Has(GMessage& msg, const char* key) const


status_t
ConfigManager::LoadFromFile(BPath path)
ConfigManager::LoadFromFile(BPath messageFilePath, BPath attributeFilePath)
{
BFile file;
status_t status = file.SetTo(path.Path(), B_READ_ONLY);
if (status == B_OK) {
GMessage fromFile;
status = fromFile.Unflatten(&file);
status_t status = B_OK;
BMessagePSP storageM(messageFilePath, PermanentStorageProvider::kPSPReadMode);
AttributePSP storageA(attributeFilePath, PermanentStorageProvider::kPSPReadMode);
GMessage msg;
int i = 0;
while (fConfiguration.FindMessage("config", i++, &msg) == B_OK) {
const char* key = msg["key"];
StorageType storageType = (StorageType)((int32)msg["storage_type"]);
status_t status = B_ERROR;
if (storageType == kStorageTypeBMessage && storageM.InitCheck() == B_OK) {
status = storageM.LoadKey(*this, key, fStorage, msg);
} else if (storageType == kStorageTypeAttribute && storageA.InitCheck() == B_OK) {
status = storageA.LoadKey(*this, key, fStorage, msg);
}
if (status == B_OK) {
GMessage msg;
int i = 0;
while (fConfiguration.FindMessage("config", i++, &msg) == B_OK) {
const char* key = msg["key"];
if (fromFile.Has(key) && _SameTypeAndFixedSize(&fromFile, key, &fStorage, key)) {
(*this)[msg["key"]] = fromFile[msg["key"]];
LogInfo("Configuration files loading value for key [%s]", (const char*)msg["key"]);
} else {
LogError("Configuration files does not contain the vaid key [%s]", (const char*)msg["key"]);
}
}
LogInfo("Config file: loaded value for key [%s] (StorageType %d)", key, storageType);
} else {
LogError("Config file: unable to get valid key [%s] (%s) (StorageType %d)", key, strerror(status), storageType);
}
}
return status;
}


status_t
ConfigManager::SaveToFile(BPath path) const
ConfigManager::SaveToFile(BPath messageFilePath, BPath attributeFilePath)
{
BFile file;
status_t status = file.SetTo(path.Path(), B_WRITE_ONLY | B_CREATE_FILE);
if (status == B_OK) {
status = fStorage.Flatten(&file);
status_t status = B_OK;
BMessagePSP storageM(messageFilePath, PermanentStorageProvider::kPSPWriteMode);
AttributePSP storageA(attributeFilePath, PermanentStorageProvider::kPSPWriteMode);
GMessage msg;
int i = 0;
while (fConfiguration.FindMessage("config", i++, &msg) == B_OK) {
const char* key = msg["key"];
status_t status = B_ERROR;
StorageType storageType = (StorageType)((int32)msg["storage_type"]);
if (storageType == kStorageTypeBMessage && storageM.InitCheck() == B_OK) {
status = storageM.SaveKey(*this, key, fStorage);
} else if (storageType == kStorageTypeAttribute && storageA.InitCheck() == B_OK) {
status = storageA.SaveKey(*this, key, fStorage);
}
if (status == B_OK) {
LogInfo("Config file: saved value for key [%s] (StorageType %d)", key, storageType);
} else {
LogError("Config file: unable to store valid key [%s] (%s) (StorageType %d)", key, strerror(status), storageType);
}
}
return status;
}
Expand Down Expand Up @@ -119,23 +251,6 @@ ConfigManager::PrintValues() const
}


bool
ConfigManager::_SameTypeAndFixedSize(BMessage* msgL, const char* keyL,
BMessage* msgR, const char* keyR) const
{
type_code typeL = 0;
bool fixedSizeL = false;
if (msgL->GetInfo(keyL, &typeL, &fixedSizeL) == B_OK) {
type_code typeR = 0;
bool fixedSizeR = false;
if (msgR->GetInfo(keyR, &typeR, &fixedSizeR) == B_OK) {
return (typeL == typeR && fixedSizeL == fixedSizeR);
}
}
return false;
}


bool
ConfigManager::_CheckKeyIsValid(const char* key) const
{
Expand Down
27 changes: 19 additions & 8 deletions src/config/ConfigManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,30 @@

#include <Autolock.h>
#include <Application.h>
#include <Path.h>

#include "GMessage.h"

enum StorageType {
kStorageTypeBMessage = 0,
kStorageTypeAttribute = 1,

kStorageTypeCountNb = 2
};

class ConfigManagerReturn;
class ConfigManager {
public:
explicit ConfigManager(const int32 messageWhat);

template<typename T>
void AddConfig(const char* group, const char* key, const char* label,
T defaultValue, GMessage* cfg = nullptr)
{
void AddConfig(const char* group,
const char* key,
const char* label,
T defaultValue,
GMessage* cfg = nullptr,
StorageType storageType = kStorageTypeBMessage) {

GMessage configKey;
if (cfg)
configKey = *cfg;
Expand All @@ -23,14 +35,15 @@ class ConfigManager {
configKey["label"] = label;
configKey["default_value"] = defaultValue;
configKey["type_code"] = MessageValue<T>::Type();
configKey["storage_type"] = (int32)storageType;

fStorage[key] = defaultValue;

fConfiguration.AddMessage("config", &configKey);
}

status_t LoadFromFile(BPath path);
status_t SaveToFile(BPath path) const;
status_t LoadFromFile(BPath messageFilePath, BPath attributeFilePath = BPath());
status_t SaveToFile(BPath messageFilePath, BPath attributeFilePath = BPath());

void ResetToDefaults();
bool HasAllDefaultValues();
Expand Down Expand Up @@ -76,9 +89,7 @@ friend ConfigManagerReturn;
BLocker fLocker;
int32 fWhat;

bool _SameTypeAndFixedSize(BMessage* msgL, const char* keyL,
BMessage* msgR, const char* keyR) const;
bool _CheckKeyIsValid(const char* key) const;
bool _CheckKeyIsValid(const char* key) const;
};


Expand Down
6 changes: 3 additions & 3 deletions src/project/ProjectFolder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ ProjectFolder::LoadSettings()

BPath path(Path());
path.Append(GenioNames::kProjectSettingsFile);
status_t status = fSettings->LoadFromFile(path.Path());
status_t status = fSettings->LoadFromFile(path.Path(), BPath(Path()));
if (status != B_OK) {
// Try to load old style settings
status = _LoadOldSettings();
Expand All @@ -194,7 +194,7 @@ ProjectFolder::SaveSettings()

BPath path(Path());
path.Append(GenioNames::kProjectSettingsFile);
status_t status = fSettings->SaveToFile(path.Path());
status_t status = fSettings->SaveToFile(path.Path(), BPath(Path()));
if (status != B_OK) {
LogErrorF("Cannot save settings: %s", ::strerror(status));
}
Expand Down Expand Up @@ -362,7 +362,7 @@ ProjectFolder::_PrepareSettings()
};
rgb_color color = ui_color(B_PANEL_BACKGROUND_COLOR);
fSettings->AddConfig("General", "color",
B_TRANSLATE("Color:"), color);
B_TRANSLATE("Color:"), color, nullptr, kStorageTypeAttribute);

fSettings->AddConfig("Build", "build_mode",
B_TRANSLATE("Build mode:"), int32(BuildMode::ReleaseMode), &buildModes);
Expand Down

0 comments on commit 6780eb5

Please sign in to comment.