diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2015-01-08 21:03:42 +0000 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2015-01-08 21:03:42 +0000 |
commit | 8da0d2348fefe074ecfb27dd20148afcbe0554ab (patch) | |
tree | 5e7f590c7067dbcbca83a6e22d0cb5437c5a731b | |
parent | Move test case into right suite (diff) | |
download | slicer-8da0d2348fefe074ecfb27dd20148afcbe0554ab.tar.bz2 slicer-8da0d2348fefe074ecfb27dd20148afcbe0554ab.tar.xz slicer-8da0d2348fefe074ecfb27dd20148afcbe0554ab.zip |
Support getting a reference to a child, for access to its metadata, and then GetChild wraps that
-rw-r--r-- | slicer/json/Jamfile.jam | 1 | ||||
-rw-r--r-- | slicer/slicer/modelParts.cpp | 14 | ||||
-rw-r--r-- | slicer/slicer/modelParts.h | 87 | ||||
-rw-r--r-- | slicer/slicer/parser.cpp | 4 | ||||
-rw-r--r-- | slicer/slicer/slicer.cpp | 36 |
5 files changed, 115 insertions, 27 deletions
diff --git a/slicer/json/Jamfile.jam b/slicer/json/Jamfile.jam index 0a0b02a..beb6679 100644 --- a/slicer/json/Jamfile.jam +++ b/slicer/json/Jamfile.jam @@ -20,6 +20,7 @@ lib slicer-json : <library>IceUtil <library>jsonpp <library>glibmm + <library>../slicer//slicer : : <library>jsonpp ; diff --git a/slicer/slicer/modelParts.cpp b/slicer/slicer/modelParts.cpp index e2711a1..b070bef 100644 --- a/slicer/slicer/modelParts.cpp +++ b/slicer/slicer/modelParts.cpp @@ -91,6 +91,20 @@ namespace Slicer { return emptyMetadata; } + ModelPartPtr + ModelPart::GetChild(const HookFilter & flt) + { + auto ref = GetChildRef(flt); + return ref ? ref->Child() : ModelPartPtr(NULL); + } + + ModelPartPtr + ModelPart::GetChild(const std::string & memberName, const HookFilter & flt) + { + auto ref = GetChildRef(memberName, flt); + return ref ? ref->Child() : ModelPartPtr(NULL); + } + template<> std::string Slicer::ModelPartForRoot<std::string>::rootName = "String"; template<> std::string Slicer::ModelPartForRoot<bool>::rootName = "Boolean"; template<> std::string Slicer::ModelPartForRoot<Ice::Float>::rootName = "Float"; diff --git a/slicer/slicer/modelParts.h b/slicer/slicer/modelParts.h index 9386696..9027f92 100644 --- a/slicer/slicer/modelParts.h +++ b/slicer/slicer/modelParts.h @@ -137,13 +137,46 @@ namespace Slicer { #undef templateMODELPARTFOR #undef MODELPARTFOR + class ChildRef : public IceUtil::Shared { + public: + virtual ModelPartPtr Child() const = 0; + virtual const Metadata & ChildMetaData() const = 0; + }; + typedef IceUtil::Handle<ChildRef> ChildRefPtr; + class DirectChildRef : public ChildRef { + public: + DirectChildRef(ModelPartPtr); + + ModelPartPtr Child() const; + const Metadata & ChildMetaData() const; + + private: + ModelPartPtr mpp; + }; + class FunctionChildRef : public ChildRef { + public: + typedef boost::function<ModelPartPtr()> ModelPartFunc; + typedef boost::function<const Metadata &()> MetadataFunc; + + FunctionChildRef(const ModelPartFunc &, const MetadataFunc &); + + ModelPartPtr Child() const; + const Metadata & ChildMetaData() const; + + private: + ModelPartFunc mpf; + MetadataFunc mdf; + }; + class ModelPart : public IceUtil::Shared { public: virtual ~ModelPart() = default; virtual void OnEachChild(const ChildHandler &) = 0; - virtual ModelPartPtr GetChild(const HookFilter & = HookFilter()) = 0; - virtual ModelPartPtr GetChild(const std::string & memberName, const HookFilter & = HookFilter()) = 0; + ModelPartPtr GetChild(const HookFilter & = HookFilter()); + ModelPartPtr GetChild(const std::string & memberName, const HookFilter & = HookFilter()); + virtual ChildRefPtr GetChildRef(const HookFilter & = HookFilter()) = 0; + virtual ChildRefPtr GetChildRef(const std::string & memberName, const HookFilter & = HookFilter()) = 0; virtual ModelPartPtr GetSubclassModelPart(const std::string &); virtual TypeId GetTypeId() const; virtual IceUtil::Optional<std::string> GetTypeIdProperty() const; @@ -173,8 +206,8 @@ namespace Slicer { { } virtual void OnEachChild(const ChildHandler &) { } - virtual ModelPartPtr GetChild(const HookFilter &) override { return NULL; } - virtual ModelPartPtr GetChild(const std::string &, const HookFilter &) override { return NULL; } + virtual ChildRefPtr GetChildRef(const HookFilter &) override { return NULL; } + virtual ChildRefPtr GetChildRef(const std::string &, const HookFilter &) override { return NULL; } virtual void SetValue(ValueSourcePtr s) override { s->set(Member); } virtual void GetValue(ValueTargetPtr s) override { s->get(Member); } virtual bool HasValue() const override { return true; } @@ -198,8 +231,8 @@ namespace Slicer { { } virtual void OnEachChild(const ChildHandler &) { } - virtual ModelPartPtr GetChild(const HookFilter &) override { return NULL; } - virtual ModelPartPtr GetChild(const std::string &, const HookFilter &) override { return NULL; } + virtual ChildRefPtr GetChildRef(const HookFilter &) override { return NULL; } + virtual ChildRefPtr GetChildRef(const std::string &, const HookFilter &) override { return NULL; } virtual void SetValue(ValueSourcePtr s) override; virtual void GetValue(ValueTargetPtr s) override; virtual bool HasValue() const override { return true; } @@ -246,17 +279,17 @@ namespace Slicer { modelPart->Create(); } } - virtual ModelPartPtr GetChild(const HookFilter & flt) override + virtual ChildRefPtr GetChildRef(const HookFilter & flt) override { if (OptionalMember) { - return modelPart->GetChild(flt); + return modelPart->GetChildRef(flt); } return NULL; } - virtual ModelPartPtr GetChild(const std::string & name, const HookFilter & flt) override + virtual ChildRefPtr GetChildRef(const std::string & name, const HookFilter & flt) override { if (OptionalMember) { - return modelPart->GetChild(name, flt); + return modelPart->GetChildRef(name, flt); } return NULL; } @@ -340,20 +373,24 @@ namespace Slicer { } } - virtual ModelPartPtr GetChild(const HookFilter & flt) override + virtual ChildRefPtr GetChildRef(const HookFilter & flt) override { for (const auto & h : hooks) { if (!flt || flt(h)) { - return h->Get(GetModel()); + return new FunctionChildRef( + boost::bind(&HookBase::Get, h, GetModel()), + boost::bind(&HookBase::GetMetadata, h)); } } return NULL; } - ModelPartPtr GetChild(const std::string & name, const HookFilter & flt) override + ChildRefPtr GetChildRef(const std::string & name, const HookFilter & flt) override { for (const auto & h : hooks) { if (h->PartName() == name && (!flt || flt(h))) { - return h->Get(GetModel()); + return new FunctionChildRef( + boost::bind(&HookBase::Get, h, GetModel()), + boost::bind(&HookBase::GetMetadata, h)); } } return NULL; @@ -467,19 +504,19 @@ namespace Slicer { } } - virtual ModelPartPtr GetChild(const HookFilter &) override + virtual ChildRefPtr GetChildRef(const HookFilter &) override { mp->Create(); - return mp; + return new DirectChildRef(mp); } - virtual ModelPartPtr GetChild(const std::string & name, const HookFilter &) override + virtual ChildRefPtr GetChildRef(const std::string & name, const HookFilter &) override { if (name != rootName) { throw IncorrectElementName(name); } mp->Create(); - return mp; + return new DirectChildRef(mp); } virtual void OnEachChild(const ChildHandler & ch) override @@ -528,13 +565,13 @@ namespace Slicer { } } - ModelPartPtr GetChild(const HookFilter &) override + ChildRefPtr GetChildRef(const HookFilter &) override { sequence.push_back(typename element_type::value_type()); - return ModelPartFor(sequence.back()); + return new DirectChildRef(ModelPartFor(sequence.back())); } - ModelPartPtr GetChild(const std::string &, const HookFilter &) override; + ChildRefPtr GetChildRef(const std::string &, const HookFilter &) override; virtual bool HasValue() const override { return true; } @@ -610,17 +647,17 @@ namespace Slicer { } } - ModelPartPtr GetChild(const HookFilter &) override + ChildRefPtr GetChildRef(const HookFilter &) override { - return new ModelPartForDictionaryElementInserter<T>(dictionary); + return new DirectChildRef(new ModelPartForDictionaryElementInserter<T>(dictionary)); } - ModelPartPtr GetChild(const std::string & name, const HookFilter &) override + ChildRefPtr GetChildRef(const std::string & name, const HookFilter &) override { if (name != pairName) { throw IncorrectElementName(name); } - return new ModelPartForDictionaryElementInserter<T>(dictionary); + return new DirectChildRef(new ModelPartForDictionaryElementInserter<T>(dictionary)); } virtual bool HasValue() const override { return true; } diff --git a/slicer/slicer/parser.cpp b/slicer/slicer/parser.cpp index 467f0ba..0e00dc1 100644 --- a/slicer/slicer/parser.cpp +++ b/slicer/slicer/parser.cpp @@ -294,7 +294,7 @@ namespace Slicer { fprintf(cpp, "// Sequence %s\n", s->name().c_str()); fprintf(cpp, "template<>\n"); - fprintf(cpp, "ModelPartPtr ModelPartForSequence< %s >::GetChild(const std::string & name, const HookFilter & flt)\n{\n", + fprintf(cpp, "ChildRefPtr ModelPartForSequence< %s >::GetChildRef(const std::string & name, const HookFilter & flt)\n{\n", s->scoped().c_str()); auto iname = metaDataValue("slicer:item:", s->getMetaData()); if (iname) { @@ -304,7 +304,7 @@ namespace Slicer { else { fprintf(cpp, "\t(void)name;\n"); } - fprintf(cpp, "\treturn GetChild(flt);\n}\n\n"); + fprintf(cpp, "\treturn GetChildRef(flt);\n}\n\n"); fprintf(cpp, "template<>\n"); fprintf(cpp, "ModelPartPtr\n"); diff --git a/slicer/slicer/slicer.cpp b/slicer/slicer/slicer.cpp index c055565..3af8bea 100644 --- a/slicer/slicer/slicer.cpp +++ b/slicer/slicer/slicer.cpp @@ -1,6 +1,7 @@ #include "slicer.h" namespace Slicer { + const Metadata emptyMetadata; #define MODELPARTFOR(Type, ModelPart) \ ModelPartPtr ModelPartFor(Type & t) { return new ModelPart< Type >(t); } \ ModelPartPtr ModelPartFor(Type * t) { return new ModelPart< Type >(t); } @@ -13,5 +14,40 @@ namespace Slicer { MODELPARTFOR(Ice::Int, ModelPartForSimple); MODELPARTFOR(Ice::Long, ModelPartForSimple); #undef MODELPARTFOR + + Slicer::FunctionChildRef::FunctionChildRef(const Slicer::FunctionChildRef::ModelPartFunc & mp, const Slicer::FunctionChildRef::MetadataFunc & md) : + mpf(mp), + mdf(md) + { + } + + ModelPartPtr + Slicer::FunctionChildRef::Child() const + { + return mpf(); + } + + const Metadata & + Slicer::FunctionChildRef::ChildMetaData() const + { + return mdf(); + } + + Slicer::DirectChildRef::DirectChildRef(ModelPartPtr m) : + mpp(m) + { + } + + ModelPartPtr + Slicer::DirectChildRef::Child() const + { + return mpp; + } + + const Metadata & + Slicer::DirectChildRef::ChildMetaData() const + { + return emptyMetadata; + } } |