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

View file

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

View file

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

View file

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

View file

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