From 112c02f40806f550370b3928f3c1965b5bee5262 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 8 May 2021 20:16:32 +0100 Subject: Implement writing shared objects with @id --- lib/persistence.h | 66 ++++++++++++++++++++++--------------------------------- 1 file changed, 26 insertions(+), 40 deletions(-) (limited to 'lib/persistence.h') diff --git a/lib/persistence.h b/lib/persistence.h index 9a143c4..0eba1ab 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -99,6 +99,7 @@ namespace Persistence { } }; + struct Persistable; struct PersistenceStore { template [[nodiscard]] inline bool persistType(const T * const, const std::type_info & ti); @@ -119,60 +120,33 @@ namespace Persistence { virtual NameAction setName(const std::string_view key) = 0; virtual void selHandler() {}; - virtual void setType(const std::string_view) = 0; + virtual void setType(const std::string_view, const Persistable *) = 0; SelectionPtr sel {}; }; struct PersistenceSelect : public PersistenceStore { - explicit PersistenceSelect(const std::string & n) : name {n} { } + explicit PersistenceSelect(const std::string & n); - NameAction - setName(const std::string_view key) override - { - return (key == name) ? NameAction::Push : NameAction::Ignore; - } + NameAction setName(const std::string_view key) override; - void - setType(const std::string_view) override - { - } + void setType(const std::string_view, const Persistable *) override; const std::string & name; }; struct PersistenceWrite : public PersistenceStore { - explicit PersistenceWrite(const Writer & o) : out {o} { } + explicit PersistenceWrite(const Writer & o, bool sh); - NameAction - setName(const std::string_view key) override - { - if (!first) { - out.nextValue(); - } - else { - first = false; - } - out.pushKey(key); - return NameAction::HandleAndContinue; - } + NameAction setName(const std::string_view key) override; - void - selHandler() override - { - this->sel->write(out); - }; + void selHandler() override; - void - setType(const std::string_view tn) override - { - out.pushKey("@typeid"); - out.pushValue(tn); - first = false; - } + void setType(const std::string_view tn, const Persistable * p) override; bool first {true}; const Writer & out; + bool shared; }; template @@ -267,6 +241,8 @@ namespace Persistence { virtual bool persist(PersistenceStore & store) = 0; + [[nodiscard]] virtual std::string getId() const; + template [[nodiscard]] constexpr static auto typeName() @@ -292,20 +268,22 @@ namespace Persistence { template inline bool - PersistenceStore::persistType(const T * const, const std::type_info & ti) + PersistenceStore::persistType(const T * const v, const std::type_info & ti) { if constexpr (!std::is_abstract_v) { [[maybe_unused]] constexpr auto f = &Persistable::addFactory; } if (typeid(std::decay_t) == ti) { - setType(Persistable::typeName()); + setType(Persistable::typeName(), v); } return true; } - // TODO Move this + // TODO Move these using SharedObjects = std::map>; inline SharedObjects sharedObjects; + using SeenSharedObjects = std::map; + inline SeenSharedObjects seenSharedObjects; template struct SelectionPtrBase : public SelectionV { using T = typename Ptr::element_type; @@ -380,7 +358,7 @@ namespace Persistence { write(const Writer & out) const override { out.beginObject(); - PersistenceWrite pw {out}; + PersistenceWrite pw {out, shared}; this->v->persist(pw); out.endObject(); } @@ -425,6 +403,14 @@ namespace Persistence { write(const Writer & out) const override { if (this->v) { + if constexpr (shared) { + if (const auto existing = seenSharedObjects.find(std::to_address(this->v)); + existing != seenSharedObjects.end()) { + out.pushValue(existing->second); + return; + } + seenSharedObjects.emplace(std::to_address(this->v), this->v->getId()); + } SelectionObj {this->v}.write(out); } else { -- cgit v1.2.3