From b6bf2ff6394363266c357180a6c683621565e4f7 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 4 Jan 2015 14:39:18 +0000 Subject: Support custom filtering of children (by hook) in GetChild --- slicer/slicer/modelParts.h | 63 ++++++++++++++++++++++++++++------------------ slicer/slicer/parser.cpp | 2 +- 2 files changed, 39 insertions(+), 26 deletions(-) diff --git a/slicer/slicer/modelParts.h b/slicer/slicer/modelParts.h index 4fb2856..7ed713f 100644 --- a/slicer/slicer/modelParts.h +++ b/slicer/slicer/modelParts.h @@ -13,6 +13,14 @@ #include namespace Slicer { + // This allows IceUtil::Handle to play nicely with boost::things + template + T * + get_pointer(const IceUtil::Handle & p) + { + return p.get(); + } + class IncorrectElementName : public std::invalid_argument { public: IncorrectElementName(const std::string & n); @@ -76,19 +84,22 @@ namespace Slicer { typedef IceUtil::Handle ValueSourcePtr; class ModelPart; + class HookCommon; typedef IceUtil::Handle ModelPartPtr; + typedef IceUtil::Handle HookCommonPtr; typedef std::map ModelParts; typedef IceUtil::Optional TypeId; - typedef boost::function ChildHandler; + typedef boost::function ChildHandler; typedef boost::function ClassRef; + typedef boost::function HookFilter; typedef std::map ClassRefMap; ClassRefMap * & classRefMap(); typedef boost::bimap ClassNameMap; ClassNameMap * & classNameMap(); - typedef std::set Metadata; + typedef std::list Metadata; enum ModelPartType { mpt_Null, mpt_Simple, @@ -97,12 +108,19 @@ namespace Slicer { mpt_Dictionary, }; + class HookCommon : public IceUtil::Shared { + public: + virtual std::string PartName() const = 0; + + virtual const Metadata & GetMetadata() const = 0; + }; + class ModelPart : public IceUtil::Shared { public: virtual ~ModelPart() = default; virtual void OnEachChild(const ChildHandler &) = 0; - virtual ModelPartPtr GetChild(const std::string & memberName) = 0; + virtual ModelPartPtr GetChild(const std::string & memberName, const HookFilter & = HookFilter()) = 0; virtual ModelPartPtr GetSubclassModelPart(const std::string &); virtual TypeId GetTypeId() const; virtual IceUtil::Optional GetTypeIdProperty() const; @@ -132,7 +150,7 @@ namespace Slicer { { } virtual void OnEachChild(const ChildHandler &) { } - virtual ModelPartPtr GetChild(const std::string &) override { return NULL; } + virtual ModelPartPtr GetChild(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; } @@ -156,7 +174,7 @@ namespace Slicer { { } virtual void OnEachChild(const ChildHandler &) { } - virtual ModelPartPtr GetChild(const std::string &) override { return NULL; } + virtual ModelPartPtr GetChild(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; } @@ -203,10 +221,10 @@ namespace Slicer { modelPart->Create(); } } - virtual ModelPartPtr GetChild(const std::string & name) override + virtual ModelPartPtr GetChild(const std::string & name, const HookFilter & flt) override { if (OptionalMember) { - return modelPart->GetChild(name); + return modelPart->GetChild(name, flt); } return NULL; } @@ -244,13 +262,9 @@ namespace Slicer { template class ModelPartForComplex : public ModelPart { public: - class HookBase : public IceUtil::Shared { + class HookBase : public HookCommon { public: virtual ModelPartPtr Get(T * t) const = 0; - - virtual std::string PartName() const = 0; - - virtual const Metadata & GetMetadata() const = 0; }; typedef IceUtil::Handle HookPtr; @@ -290,17 +304,16 @@ namespace Slicer { { for (const auto & h : hooks) { auto modelPart = h->Get(GetModel()); - ch(h->PartName(), modelPart && modelPart->HasValue() ? modelPart : ModelPartPtr()); + ch(h->PartName(), modelPart && modelPart->HasValue() ? modelPart : ModelPartPtr(), h); } } - ModelPartPtr GetChild(const std::string & name) override + ModelPartPtr GetChild(const std::string & name, const HookFilter & flt) override { - auto childitr = std::find_if(hooks.begin(), hooks.end(), [&name](const typename Hooks::value_type & h) { - return h->PartName() == name; - }); - if (childitr != hooks.end()) { - return (*childitr)->Get(GetModel()); + for (const auto & h : hooks) { + if (h->PartName() == name && (!flt || flt(h))) { + return h->Get(GetModel()); + } } return NULL; } @@ -403,7 +416,7 @@ namespace Slicer { ModelObject = o; } - virtual ModelPartPtr GetChild(const std::string & name) override + virtual ModelPartPtr GetChild(const std::string & name, const HookFilter &) override { if (!name.empty() && name != rootName) { throw IncorrectElementName(rootName); @@ -414,7 +427,7 @@ namespace Slicer { virtual void OnEachChild(const ChildHandler & ch) override { - ch(rootName, new ModelPartForClass(ModelObject)); + ch(rootName, new ModelPartForClass(ModelObject), NULL); } typename T::element_type * GetModel() override @@ -447,11 +460,11 @@ namespace Slicer { virtual void OnEachChild(const ChildHandler & ch) override { for(auto & element : sequence) { - ch(elementName, elementModelPart(element)); + ch(elementName, elementModelPart(element), NULL); } } - ModelPartPtr GetChild(const std::string &) override; + ModelPartPtr GetChild(const std::string &, const HookFilter &) override; virtual bool HasValue() const override { return true; } @@ -523,10 +536,10 @@ namespace Slicer { virtual void OnEachChild(const ChildHandler & ch) override { for (auto & pair : dictionary) { - ch(pairName, new ModelPartForDictionaryElement(const_cast(&pair.first), &pair.second)); + ch(pairName, new ModelPartForDictionaryElement(const_cast(&pair.first), &pair.second), NULL); } } - ModelPartPtr GetChild(const std::string & name) override + ModelPartPtr GetChild(const std::string & name, const HookFilter &) override { if (!name.empty() && name != pairName) { throw IncorrectElementName(pairName); diff --git a/slicer/slicer/parser.cpp b/slicer/slicer/parser.cpp index bdd42ec..96dd9b6 100644 --- a/slicer/slicer/parser.cpp +++ b/slicer/slicer/parser.cpp @@ -285,7 +285,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)\n{\n", + fprintf(cpp, "ModelPartPtr ModelPartForSequence< %s >::GetChild(const std::string & name, const HookFilter &)\n{\n", s->scoped().c_str()); auto iname = metaDataValue("slicer:item:", s->getMetaData()); if (iname) { -- cgit v1.2.3