internal: various stability improvements

This commit is contained in:
Vaxry 2024-02-11 15:38:51 +00:00
parent c1f5b0ab48
commit 7c5f672b2f
5 changed files with 102 additions and 36 deletions

View file

@ -165,6 +165,7 @@ namespace Hyprlang {
PCONFIGCUSTOMVALUEDESTRUCTOR dtor = nullptr;
void* data = nullptr;
std::string defaultVal = "";
std::string lastVal = "";
friend class CConfigValue;
friend class CConfig;
@ -245,7 +246,8 @@ namespace Hyprlang {
eDataType m_eType = eDataType::CONFIGDATATYPE_EMPTY;
void* m_pData = nullptr;
void defaultFrom(SConfigDefaultValue& ref);
void setFrom(std::any value);
void setFrom(std::any ref);
void setFrom(const CConfigValue* const ref);
friend class CConfig;
};

View file

@ -17,46 +17,52 @@ void CParseResult::setError(const char* err) {
}
CConfigValue::~CConfigValue() {
if (m_eType == CONFIGDATATYPE_CUSTOM)
reinterpret_cast<CConfigCustomValueType*>(m_pData)->dtor(&reinterpret_cast<CConfigCustomValueType*>(m_pData)->data);
if (m_pData) {
switch (m_eType) {
case CONFIGDATATYPE_INT: delete (int64_t*)m_pData; break;
case CONFIGDATATYPE_FLOAT: delete (float*)m_pData; break;
case CONFIGDATATYPE_VEC2: delete (SVector2D*)m_pData; break;
case CONFIGDATATYPE_CUSTOM: delete (CConfigCustomValueType*)m_pData; break;
case CONFIGDATATYPE_STR: delete[] (char*)m_pData; break;
if (m_pData)
free(m_pData);
default: break; // oh no?
}
}
}
CConfigValue::CConfigValue(const int64_t value) {
m_pData = calloc(1, sizeof(int64_t));
m_pData = new int64_t;
*reinterpret_cast<int64_t*>(m_pData) = value;
m_eType = CONFIGDATATYPE_INT;
}
CConfigValue::CConfigValue(const float value) {
m_pData = calloc(1, sizeof(float));
m_pData = new float;
*reinterpret_cast<float*>(m_pData) = value;
m_eType = CONFIGDATATYPE_FLOAT;
}
CConfigValue::CConfigValue(const SVector2D value) {
m_pData = calloc(1, sizeof(SVector2D));
m_pData = new SVector2D;
*reinterpret_cast<SVector2D*>(m_pData) = value;
m_eType = CONFIGDATATYPE_VEC2;
}
CConfigValue::CConfigValue(const char* value) {
m_pData = calloc(1, strlen(value) + 1);
m_pData = new char[strlen(value) + 1];
strncpy((char*)m_pData, value, strlen(value));
m_eType = CONFIGDATATYPE_STR;
((char*)m_pData)[strlen(value)] = '\0';
m_eType = CONFIGDATATYPE_STR;
}
CConfigValue::CConfigValue(CConfigCustomValueType&& value) {
m_pData = calloc(1, sizeof(CConfigCustomValueType));
new (m_pData) CConfigCustomValueType(value);
m_pData = new CConfigCustomValueType(value);
m_eType = CONFIGDATATYPE_CUSTOM;
}
CConfigValue::CConfigValue(const CConfigValue& other) {
m_eType = other.m_eType;
setFrom(other.getValue());
setFrom(&other);
}
CConfigValue::CConfigValue() {
@ -75,6 +81,7 @@ CConfigCustomValueType::CConfigCustomValueType(PCONFIGCUSTOMVALUEHANDLERFUNC han
handler = handler_;
dtor = dtor_;
defaultVal = def;
lastVal = def;
}
CConfigCustomValueType::~CConfigCustomValueType() {
@ -86,37 +93,37 @@ void CConfigValue::defaultFrom(SConfigDefaultValue& ref) {
switch (m_eType) {
case CONFIGDATATYPE_FLOAT: {
if (!m_pData)
m_pData = calloc(1, sizeof(float));
m_pData = new float;
*reinterpret_cast<float*>(m_pData) = std::any_cast<float>(ref.data);
break;
}
case CONFIGDATATYPE_INT: {
if (!m_pData)
m_pData = calloc(1, sizeof(int64_t));
m_pData = new int64_t;
*reinterpret_cast<int64_t*>(m_pData) = std::any_cast<int64_t>(ref.data);
break;
}
case CONFIGDATATYPE_STR: {
if (m_pData)
free(m_pData);
delete[] (char*)m_pData;
std::string str = std::any_cast<std::string>(ref.data);
m_pData = calloc(1, str.length() + 1);
strncpy((char*)m_pData, str.c_str(), str.length());
m_pData = new char[str.length() + 1];
strncpy((char*)m_pData, str.c_str(), str.length()); // TODO: please just wrap this
((char*)m_pData)[str.length()] = '\0';
break;
}
case CONFIGDATATYPE_VEC2: {
if (!m_pData)
m_pData = calloc(1, sizeof(SVector2D));
m_pData = new SVector2D;
*reinterpret_cast<SVector2D*>(m_pData) = std::any_cast<SVector2D>(ref.data);
break;
}
case CONFIGDATATYPE_CUSTOM: {
if (!m_pData)
m_pData = calloc(1, sizeof(CConfigCustomValueType));
m_pData = new CConfigCustomValueType(ref.handler, ref.dtor, std::any_cast<std::string>(ref.data).c_str());
CConfigCustomValueType* type = reinterpret_cast<CConfigCustomValueType*>(m_pData);
type->handler = ref.handler;
type->dtor = ref.dtor;
type->handler(std::any_cast<std::string>(ref.data).c_str(), &type->data);
type->lastVal = std::any_cast<std::string>(ref.data);
break;
}
default: {
@ -127,35 +134,84 @@ void CConfigValue::defaultFrom(SConfigDefaultValue& ref) {
m_bSetByUser = false;
}
void CConfigValue::setFrom(std::any value) {
void CConfigValue::setFrom(const CConfigValue* const ref) {
switch (m_eType) {
case CONFIGDATATYPE_FLOAT: {
*reinterpret_cast<float*>(m_pData) = std::any_cast<float>(value);
if (!m_pData)
m_pData = new float;
*reinterpret_cast<float*>(m_pData) = std::any_cast<float>(ref->getValue());
break;
}
case CONFIGDATATYPE_INT: {
*reinterpret_cast<int64_t*>(m_pData) = std::any_cast<int64_t>(value);
if (!m_pData)
m_pData = new int64_t;
*reinterpret_cast<int64_t*>(m_pData) = std::any_cast<int64_t>(ref->getValue());
break;
}
case CONFIGDATATYPE_STR: {
if (m_pData)
free(m_pData);
std::string str = std::any_cast<std::string>(value);
m_pData = calloc(1, str.length() + 1);
delete[] (char*)m_pData;
std::string str = std::any_cast<std::string>(ref->getValue());
m_pData = new char[str.length() + 1];
strncpy((char*)m_pData, str.c_str(), str.length());
((char*)m_pData)[str.length()] = '\0';
break;
}
case CONFIGDATATYPE_VEC2: {
*reinterpret_cast<SVector2D*>(m_pData) = std::any_cast<SVector2D>(value);
if (!m_pData)
m_pData = new SVector2D;
*reinterpret_cast<SVector2D*>(m_pData) = std::any_cast<SVector2D>(ref->getValue());
break;
}
case CONFIGDATATYPE_CUSTOM: {
CConfigCustomValueType* reftype = reinterpret_cast<CConfigCustomValueType*>(ref->m_pData);
if (!m_pData)
m_pData = new CConfigCustomValueType(reftype->handler, reftype->dtor, reftype->defaultVal.c_str());
CConfigCustomValueType* type = reinterpret_cast<CConfigCustomValueType*>(m_pData);
type->handler(reftype->lastVal.c_str(), &type->data);
break;
}
default: {
throw "bad defaultFrom type";
}
}
}
void CConfigValue::setFrom(std::any ref) {
switch (m_eType) {
case CONFIGDATATYPE_FLOAT: {
if (!m_pData)
m_pData = new float;
*reinterpret_cast<float*>(m_pData) = std::any_cast<float>(ref);
break;
}
case CONFIGDATATYPE_INT: {
if (!m_pData)
m_pData = new int64_t;
*reinterpret_cast<int64_t*>(m_pData) = std::any_cast<int64_t>(ref);
break;
}
case CONFIGDATATYPE_STR: {
if (m_pData)
delete[] (char*)m_pData;
std::string str = std::any_cast<std::string>(ref);
m_pData = new char[str.length() + 1];
strncpy((char*)m_pData, str.c_str(), str.length());
((char*)m_pData)[str.length()] = '\0';
break;
}
case CONFIGDATATYPE_VEC2: {
if (!m_pData)
m_pData = new SVector2D;
*reinterpret_cast<SVector2D*>(m_pData) = std::any_cast<SVector2D>(ref);
break;
}
case CONFIGDATATYPE_CUSTOM: {
throw "bad defaultFrom type (cannot custom from std::any)";
break;
}
// case CONFIGDATATYPE_CUSTOM: {
// CConfigCustomValueType* type = reinterpret_cast<CConfigCustomValueType*>(m_pData);
// type->handler = ref.handler;
// type->dtor = ref.dtor;
// type->handler(std::any_cast<std::string>(ref.data).c_str(), &type->data);
// break;
// }
default: {
throw "bad defaultFrom type";
}

View file

@ -351,6 +351,7 @@ CParseResult CConfig::configSetValueSafe(const std::string& command, const std::
}
case CConfigValue::eDataType::CONFIGDATATYPE_CUSTOM: {
reinterpret_cast<CConfigCustomValueType*>(VALUEIT->second.m_pData)->handler(value.c_str(), &reinterpret_cast<CConfigCustomValueType*>(VALUEIT->second.m_pData)->data);
reinterpret_cast<CConfigCustomValueType*>(VALUEIT->second.m_pData)->lastVal = value;
break;
}
default: {

View file

@ -44,6 +44,7 @@ special {
specialGeneric {
one {
value = 1
copyTest = 2
}
two {

View file

@ -115,6 +115,9 @@ int main(int argc, char** argv, char** envp) {
config.addSpecialCategory("specialGeneric:two", {nullptr, true});
config.addSpecialConfigValue("specialGeneric:two", "value", 0L);
const Hyprlang::CConfigValue copyTest = {1L};
config.addSpecialConfigValue("specialGeneric:one", "copyTest", copyTest);
const auto PARSERESULT = config.parse();
if (PARSERESULT.error) {
std::cout << "Parse error: " << PARSERESULT.getError() << "\n";
@ -180,6 +183,9 @@ int main(int argc, char** argv, char** envp) {
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialGeneric:one", "value")), 1);
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialGeneric:two", "value")), 2);
// test copying
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialGeneric:one", "copyTest")), 2);
// test sourcing
std::cout << " → Testing sourcing\n";
EXPECT(std::any_cast<int64_t>(config.getConfigValue("myColors:pink")), 0xFFc800c8L);