mirror of
https://github.com/hyprwm/hyprlang.git
synced 2024-12-22 01:49:49 +01:00
API: add a templated config value wrapper
This is basically a copy of the Hyprland config wrapper. It's much more straightforward to use, and much harder to fuck up.
This commit is contained in:
parent
f054f2e44d
commit
058fcf84c9
4 changed files with 98 additions and 3 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -12,4 +12,5 @@ _deps
|
|||
.vscode
|
||||
build/
|
||||
doxygen/
|
||||
doxygen-awesome-css/
|
||||
doxygen-awesome-css/
|
||||
.cache/
|
|
@ -3,11 +3,13 @@
|
|||
#ifndef HYPRLANG_HPP
|
||||
#define HYPRLANG_HPP
|
||||
|
||||
#include <typeindex>
|
||||
#include <any>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
#include <print>
|
||||
#include <cstdlib>
|
||||
|
||||
class CConfigImpl;
|
||||
struct SConfigDefaultValue;
|
||||
|
@ -452,6 +454,87 @@ namespace Hyprlang {
|
|||
void retrieveKeysForCat(const char* category, const char*** out, size_t* len);
|
||||
CParseResult parseRawStream(const std::string& stream);
|
||||
};
|
||||
|
||||
/*!
|
||||
Templated wrapper for Hyprlang values. Much more straightforward to use.
|
||||
|
||||
\since 0.6.0
|
||||
*/
|
||||
template <typename T>
|
||||
class CSimpleConfigValue {
|
||||
public:
|
||||
CSimpleConfigValue(CConfig* const pConfig, const char* val) {
|
||||
const auto VAL = pConfig->getConfigValuePtr(val);
|
||||
|
||||
if (!VAL) {
|
||||
std::println("CSimpleConfigValue: value not found");
|
||||
abort();
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE
|
||||
p_ = VAL->getDataStaticPtr();
|
||||
|
||||
#ifdef HYPRLAND_DEBUG
|
||||
// verify type
|
||||
const auto ANY = VAL->getValue();
|
||||
const auto TYPE = std::type_index(ANY.type());
|
||||
|
||||
// exceptions
|
||||
const bool STRINGEX = (typeid(T) == typeid(std::string) && TYPE == typeid(Hyprlang::STRING));
|
||||
const bool CUSTOMEX = (typeid(T) == typeid(Hyprlang::CUSTOMTYPE) && (TYPE == typeid(Hyprlang::CUSTOMTYPE*) || TYPE == typeid(void*) /* dunno why it does this? */));
|
||||
|
||||
if (typeid(T) != TYPE && !STRINGEX && !CUSTOMEX) {
|
||||
std::println("CSimpleConfigValue: Mismatched type in CConfigValue<T>, got {} but has {}", typeid(T).name(), TYPE.name());
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
T* ptr() const {
|
||||
return *(T* const*)p_;
|
||||
}
|
||||
|
||||
T operator*() const {
|
||||
return *ptr();
|
||||
}
|
||||
|
||||
private:
|
||||
void* const* p_ = nullptr;
|
||||
};
|
||||
|
||||
template <>
|
||||
inline std::string* CSimpleConfigValue<std::string>::ptr() const {
|
||||
std::print("Impossible to implement ptr() of CConfigValue<std::string>");
|
||||
abort();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline std::string CSimpleConfigValue<std::string>::operator*() const {
|
||||
return std::string{*(Hyprlang::STRING*)p_};
|
||||
}
|
||||
|
||||
template <>
|
||||
inline Hyprlang::STRING* CSimpleConfigValue<Hyprlang::STRING>::ptr() const {
|
||||
return (Hyprlang::STRING*)p_;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline Hyprlang::STRING CSimpleConfigValue<Hyprlang::STRING>::operator*() const {
|
||||
return *(Hyprlang::STRING*)p_;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline Hyprlang::CUSTOMTYPE* CSimpleConfigValue<Hyprlang::CUSTOMTYPE>::ptr() const {
|
||||
return *(Hyprlang::CUSTOMTYPE* const*)p_;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline Hyprlang::CUSTOMTYPE CSimpleConfigValue<Hyprlang::CUSTOMTYPE>::operator*() const {
|
||||
std::print("Impossible to implement operator* of CConfigValue<Hyprlang::CUSTOMTYPE>, use ptr()");
|
||||
abort();
|
||||
return *ptr();
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef HYPRLANG_INTERNAL
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
struct SHandler {
|
||||
std::string name = "";
|
||||
|
|
|
@ -185,6 +185,16 @@ int main(int argc, char** argv, char** envp) {
|
|||
EXPECT(ignoreKeyword, "aaa");
|
||||
EXPECT(useKeyword, "yes");
|
||||
|
||||
// Test templated wrapper
|
||||
auto T1 = Hyprlang::CSimpleConfigValue<Hyprlang::INT>(&config, "testInt");
|
||||
auto T2 = Hyprlang::CSimpleConfigValue<Hyprlang::FLOAT>(&config, "testFloat");
|
||||
auto T3 = Hyprlang::CSimpleConfigValue<Hyprlang::SVector2D>(&config, "testVec");
|
||||
auto T4 = Hyprlang::CSimpleConfigValue<std::string>(&config, "testString");
|
||||
EXPECT(*T1, 123);
|
||||
EXPECT(*T2, 123.456F);
|
||||
EXPECT(*T3, EXP);
|
||||
EXPECT(*T4, "Hello World! # This is not a comment!");
|
||||
|
||||
// test static values
|
||||
std::cout << " → Testing static values\n";
|
||||
static auto* const PTESTINT = config.getConfigValuePtr("testInt")->getDataStaticPtr();
|
||||
|
|
Loading…
Reference in a new issue