From 375652641509b75e93a284deea44f6f1be13e7b3 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 20 Feb 2023 18:24:54 +0000 Subject: Swap @ prefix for p. prefix for special value names --- lib/persistence.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/persistence.h') diff --git a/lib/persistence.h b/lib/persistence.h index 4fbff4c..c311067 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -340,14 +340,14 @@ namespace Persistence { select(const std::string & mbr) override { using namespace std::literals; - if (mbr == "@typeid"sv) { + if (mbr == "p.typeid"sv) { if (this->v) { throw std::runtime_error("cannot set object type after creation"); } return this->template make_s(this->v); } if constexpr (shared) { - if (mbr == "@id"sv) { + if (mbr == "p.id"sv) { return this->template make_s(this->v); } } -- cgit v1.2.3 From eeb3bceceacff5807011c83eeaa1f1497429b3ab Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 20 Feb 2023 18:59:18 +0000 Subject: Make sure an object is created before remembering it --- lib/persistence.h | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/persistence.h') diff --git a/lib/persistence.h b/lib/persistence.h index c311067..dbaee44 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -348,6 +348,7 @@ namespace Persistence { } if constexpr (shared) { if (mbr == "p.id"sv) { + make_default_as_needed(this->v); return this->template make_s(this->v); } } -- cgit v1.2.3 From 223ecbc450fede9f8ca246895d5f82495f8665e8 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 20 Feb 2023 19:14:55 +0000 Subject: Allow override member variable names and selection helper when mapping members for persistence --- lib/persistence.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'lib/persistence.h') diff --git a/lib/persistence.h b/lib/persistence.h index dbaee44..e1f7605 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -113,14 +113,14 @@ namespace Persistence { template [[nodiscard]] inline bool persistType(const T * const, const std::type_info & ti); enum class NameAction { Push, HandleAndContinue, Ignore }; - template + template [[nodiscard]] inline bool persistValue(const std::string_view key, T & value) { - SelectionT s {value}; - const auto act {setName(key, s)}; + auto s = std::make_unique(value); + const auto act {setName(key, *s)}; if (act != NameAction::Ignore) { - sel = std::make_unique(std::move(s)); + sel = std::move(s); if (act == NameAction::HandleAndContinue) { selHandler(); } @@ -462,4 +462,7 @@ namespace Persistence { } #define STORE_TYPE store.persistType(this, typeid(*this)) -#define STORE_MEMBER(mbr) store.persistValue(#mbr, mbr) +#define STORE_MEMBER(mbr) STORE_NAME_MEMBER(#mbr, mbr) +#define STORE_NAME_MEMBER(name, mbr) store.persistValue>(name, mbr) +#define STORE_HELPER(mbr, Helper) STORE_NAME_HELPER(#mbr, mbr, Helper) +#define STORE_NAME_HELPER(name, mbr, Helper) store.persistValue(name, mbr) -- cgit v1.2.3 From a142b8da33e6c6657a7aa529ddf0f1c0882ff0d5 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 20 Feb 2023 23:59:24 +0000 Subject: Accept a CSV for glm::vec data --- lib/persistence.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'lib/persistence.h') diff --git a/lib/persistence.h b/lib/persistence.h index e1f7605..01b2a7e 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -187,6 +188,17 @@ namespace Persistence { }; using SelectionV::SelectionV; + using SelectionV::setValue; + + void + setValue(std::string && s) override + { + std::stringstream ss {std::move(s)}; + for (glm::length_t n = 0; n < L; n += 1) { + ss >> this->v[n]; + ss.get(); + } + } void beginArray(Stack & stk) override -- cgit v1.2.3 From bf0a1a219e48007ca51e23ea45d08d295e398fcd Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 21 Feb 2023 00:03:08 +0000 Subject: Add helper Selection to insert into a map based on a member value as key --- lib/persistence.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'lib/persistence.h') diff --git a/lib/persistence.h b/lib/persistence.h index 01b2a7e..d55062a 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -256,6 +256,23 @@ namespace Persistence { } }; + template + struct MapByMember : public Persistence::SelectionT> { + MapByMember(Map & m) : Persistence::SelectionT> {s}, map {m} { } + + using Persistence::SelectionT>::SelectionT; + void + endObject(Persistence::Stack & stk) override + { + map.emplace(std::invoke(Key, s), s); + stk.pop(); + } + + private: + std::shared_ptr s; + Map & map; + }; + struct Persistable { Persistable() = default; virtual ~Persistable() = default; -- cgit v1.2.3 From f91e2ea8d9e30b1e62c4f8784fddfd4eb9578d2d Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 21 Feb 2023 20:09:41 +0000 Subject: Move Appender in Persistence NS and simplify types --- lib/persistence.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'lib/persistence.h') diff --git a/lib/persistence.h b/lib/persistence.h index d55062a..5c8454c 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -273,6 +273,22 @@ namespace Persistence { Map & map; }; + template + struct Appender : public Persistence::SelectionT { + Appender(Container & c) : Persistence::SelectionT {s}, container {c} { } + using Persistence::SelectionT::SelectionT; + void + endObject(Persistence::Stack & stk) override + { + container.emplace_back(std::move(s)); + stk.pop(); + } + + private: + Type s; + Container & container; + }; + struct Persistable { Persistable() = default; virtual ~Persistable() = default; -- cgit v1.2.3 From 320e5cc574f0c8f83def034e36f6d0c57b1f75ac Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 22 Feb 2023 20:54:39 +0000 Subject: Fixup MapByMember to work with shared or unique ptr --- lib/persistence.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'lib/persistence.h') diff --git a/lib/persistence.h b/lib/persistence.h index 5c8454c..0fc0200 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -256,20 +256,20 @@ namespace Persistence { } }; - template - struct MapByMember : public Persistence::SelectionT> { - MapByMember(Map & m) : Persistence::SelectionT> {s}, map {m} { } + template + struct MapByMember : public Persistence::SelectionT { + MapByMember(Map & m) : Persistence::SelectionT {s}, map {m} { } - using Persistence::SelectionT>::SelectionT; + using Persistence::SelectionT::SelectionT; void endObject(Persistence::Stack & stk) override { - map.emplace(std::invoke(Key, s), s); + map.emplace(std::invoke(Key, s), std::move(s)); stk.pop(); } private: - std::shared_ptr s; + Type s; Map & map; }; -- cgit v1.2.3 From b59ba638083122456bfeab0ff1fc7e3f3af99423 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 23 Feb 2023 00:39:06 +0000 Subject: Support parsing string values in persistence read --- lib/persistence.h | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) (limited to 'lib/persistence.h') diff --git a/lib/persistence.h b/lib/persistence.h index 0fc0200..bfd27f0 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -87,13 +88,53 @@ namespace Persistence { T & v; }; - template struct SelectionT : public SelectionV { + template + concept Scalar = std::is_scalar_v; + template + concept NotScalar = (!Scalar); + + template struct SelectionT : public SelectionV { + using SelectionV::SelectionV; + using Selection::setValue; + + void + setValue(T evalue) override + { + std::swap(this->v, evalue); + } + + void + setValue(std::string && evalue) override + { + if constexpr (std::same_as) { + using namespace std::literals; + if (!(this->v = evalue == "true"sv)) { + if (evalue != "false"sv) { + throw std::runtime_error("Value conversion failure"); + } + } + } + else { + if (auto res = std::from_chars(evalue.c_str(), evalue.c_str() + evalue.length(), this->v).ec; + res != std::errc {}) { + throw std::runtime_error("Value conversion failure"); + } + } + } + + void + write(const Writer & out) const override + { + out.pushValue(this->v); + } + }; + + template struct SelectionT : public SelectionV { using SelectionV::SelectionV; using Selection::setValue; - using P = std::conditional_t, T, T &&>; void - setValue(P evalue) override + setValue(T && evalue) override { std::swap(this->v, evalue); } -- cgit v1.2.3 From 7a70e75656d31428c9bbbd51fbf1ca920e577ed1 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 28 Feb 2023 01:24:18 +0000 Subject: Remove to specify if the Selection pointer type is shared or not Inferred based on whether the pointer is copyable or not. --- lib/persistence.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'lib/persistence.h') diff --git a/lib/persistence.h b/lib/persistence.h index bfd27f0..458ba4d 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -381,7 +381,8 @@ namespace Persistence { using SeenSharedObjects = std::map; inline SeenSharedObjects seenSharedObjects; - template struct SelectionPtrBase : public SelectionV { + template struct SelectionPtrBase : public SelectionV { + static constexpr auto shared = std::is_copy_assignable_v; using T = typename Ptr::element_type; struct SelectionObj : public SelectionV { struct MakeObjectByTypeName : public SelectionV { @@ -526,13 +527,13 @@ namespace Persistence { } }; - template struct SelectionT> : public SelectionPtrBase, false> { - using SelectionPtrBase, false>::SelectionPtrBase; + template struct SelectionT> : public SelectionPtrBase> { + using SelectionPtrBase>::SelectionPtrBase; }; - template struct SelectionT> : public SelectionPtrBase, true> { - using SelectionPtrBase, true>::SelectionPtrBase; - using SelectionPtrBase, true>::setValue; + template struct SelectionT> : public SelectionPtrBase> { + using SelectionPtrBase>::SelectionPtrBase; + using SelectionPtrBase>::setValue; void setValue(std::string && id) override -- cgit v1.2.3 From 17ac090dd1dd245cf1e24b62b7333ba9be571bde Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 2 Mar 2023 18:36:34 +0000 Subject: Add ParseBase Acts as a base class for persistence parser, encompasses the parse stack and manages shared objects --- lib/persistence.h | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'lib/persistence.h') diff --git a/lib/persistence.h b/lib/persistence.h index 458ba4d..05cb49b 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -375,9 +375,36 @@ namespace Persistence { return true; } + class ParseBase { + public: + using SharedObjects = std::map>; + using SharedObjectsWPtr = std::weak_ptr; + using SharedObjectsPtr = std::shared_ptr; + + ParseBase(); + DEFAULT_MOVE_NO_COPY(ParseBase); + + template + static auto + getShared(auto && k) + { + return std::dynamic_pointer_cast(Persistence::ParseBase::sharedObjects.lock()->at(k)); + } + template + static auto + emplaceShared(T &&... v) + { + return sharedObjects.lock()->emplace(std::forward(v)...); + } + + protected: + Stack stk; + + private: + inline static thread_local SharedObjectsWPtr sharedObjects; + SharedObjectsPtr sharedObjectsInstance; + }; // TODO Move these - using SharedObjects = std::map>; - inline SharedObjects sharedObjects; using SeenSharedObjects = std::map; inline SeenSharedObjects seenSharedObjects; @@ -417,7 +444,7 @@ namespace Persistence { void setValue(std::string && id) override { - sharedObjects.emplace(id, this->v); + ParseBase::emplaceShared(id, this->v); } }; @@ -538,7 +565,7 @@ namespace Persistence { void setValue(std::string && id) override { - if (auto teo = std::dynamic_pointer_cast(sharedObjects.at(id))) { + if (auto teo = ParseBase::getShared(id)) { this->v = std::move(teo); } else { -- cgit v1.2.3