diff --git a/libstarlight/source/starlight/datatypes/Optional.h b/libstarlight/source/starlight/datatypes/Optional.h new file mode 100644 index 0000000..00c921c --- /dev/null +++ b/libstarlight/source/starlight/datatypes/Optional.h @@ -0,0 +1,63 @@ +#pragma once +#include "starlight/_global.h" + +#include + +namespace starlight { + template + class Optional { + private: + std::unique_ptr p = nullptr; + std::function* getdef = nullptr; + + inline void initp() { + if (!p) { + p = std::make_unique(); + if (getdef) *p = (*getdef)(); + } + } + + public: + Optional() = default; + Optional(std::function* getDefault) : getdef(getDefault) { } + Optional(nullptr_t) : p(nullptr) { } + Optional(const Optional& o) { // copy operator *actually copies the inner object* + if (o.p) { + p = std::make_unique(); + *p = *o.p; + } + getdef = o.getdef; + } + + Optional& operator=(const nullptr_t&) { p.reset(); } + Optional& operator=(const T& o) { // assign by type's assignment operator if passed a "value" + if (!p) p = std::make_unique(); + *p = o; + return *this; + } + + T& operator *() { + initp(); + return *p; + } + + T* operator ->() { + initp(); + return &*p; + } + + inline T& Get(T& defaultRef) { + if (p) return *p; + return defaultRef; + } + + inline T& ROGet() { + if (p) return *p; + if (getdef) return (*getdef)(); + static T fb; return fb; // meh, hackish but you shouldn't do this without a getdef anyway + // todo: clean this up somehow ^ (throw instead? or maybe have a static unique_ptr instead so we save memory when this is never called for a type) + } + + // + }; +} diff --git a/libstarlight/source/starlight/dialog/OSK.cpp b/libstarlight/source/starlight/dialog/OSK.cpp index bf1ccdf..e8234fa 100644 --- a/libstarlight/source/starlight/dialog/OSK.cpp +++ b/libstarlight/source/starlight/dialog/OSK.cpp @@ -96,7 +96,8 @@ OSK::OSK(osk::InputHandler* handler) : Form(true), handler(handler) { bpen = bpstart + bs * Vector2(linestart[3] + 10, 3); auto key = std::make_shared