summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2015-01-04 14:39:18 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2015-01-04 15:52:05 +0000
commitb6bf2ff6394363266c357180a6c683621565e4f7 (patch)
tree964338dd9c24802afcbe37c19ecbbe5114835e87
parentSplit metadata helpers into their own file (diff)
downloadslicer-b6bf2ff6394363266c357180a6c683621565e4f7.tar.bz2
slicer-b6bf2ff6394363266c357180a6c683621565e4f7.tar.xz
slicer-b6bf2ff6394363266c357180a6c683621565e4f7.zip
Support custom filtering of children (by hook) in GetChild
-rw-r--r--slicer/slicer/modelParts.h63
-rw-r--r--slicer/slicer/parser.cpp2
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 <vector>
namespace Slicer {
+ // This allows IceUtil::Handle to play nicely with boost::things
+ template <class T>
+ T *
+ get_pointer(const IceUtil::Handle<T> & 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<ValueSource> ValueSourcePtr;
class ModelPart;
+ class HookCommon;
typedef IceUtil::Handle<ModelPart> ModelPartPtr;
+ typedef IceUtil::Handle<HookCommon> HookCommonPtr;
typedef std::map<std::string, ModelPartPtr> ModelParts;
typedef IceUtil::Optional<std::string> TypeId;
- typedef boost::function<void(const std::string &, ModelPartPtr)> ChildHandler;
+ typedef boost::function<void(const std::string &, ModelPartPtr, HookCommonPtr)> ChildHandler;
typedef boost::function<ModelPartPtr(void *)> ClassRef;
+ typedef boost::function<bool(HookCommonPtr)> HookFilter;
typedef std::map<std::string, ClassRef> ClassRefMap;
ClassRefMap * & classRefMap();
typedef boost::bimap<std::string, std::string> ClassNameMap;
ClassNameMap * & classNameMap();
- typedef std::set<std::string> Metadata;
+ typedef std::list<std::string> 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<std::string> 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<typename T>
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<HookBase> 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<T>(ModelObject));
+ ch(rootName, new ModelPartForClass<T>(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<T>(const_cast<typename T::key_type *>(&pair.first), &pair.second));
+ ch(pairName, new ModelPartForDictionaryElement<T>(const_cast<typename T::key_type *>(&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) {