summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2015-01-08 21:03:42 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2015-01-08 21:03:42 +0000
commit8da0d2348fefe074ecfb27dd20148afcbe0554ab (patch)
tree5e7f590c7067dbcbca83a6e22d0cb5437c5a731b
parentMove test case into right suite (diff)
downloadslicer-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.jam1
-rw-r--r--slicer/slicer/modelParts.cpp14
-rw-r--r--slicer/slicer/modelParts.h87
-rw-r--r--slicer/slicer/parser.cpp4
-rw-r--r--slicer/slicer/slicer.cpp36
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;
+ }
}