I’d appreciate some feedback on how disgusting a misuse of the technology this following approach is; ValueTree is still pretty new business, so there’s little in the way of precedent/example to work from.
WHAT
I am using a ValueTree to hold all the data in my UserDocument. This is lovely.
I also make use of a ‘NameRegister’ class (used to handle/intercept name clashes when creating/editing nodes).
HOWEVER, whilst I can easily have a ‘NameRegister’ in my UserDocument class to handle one set of names, I also need each child of a particular node to have its own corresponding NameRegister [i.e., only name clashes within a given node branch are forbidden].
In EASYWORDS, certain ValueTree nodes must have an associated non-ValueTree instance.
The obvious idea for implementing this was to have a mapping in the UserDocument class. There would be a ‘getNameRegisterForNode(ValueTree)’ function, which would pick out the right one when needed. This approach is a bit messy though; changes to these nodes would also have to be paired with some kind of fixup operation on that separate map. I don’t want to have to deal with that!
So, what I’ve been experimenting with is wrapping such associated ‘real objects’ in a DynamicObject, and storing them within the ValueTree itself. This means I can access them directly from the node, and not have to worry about keeping a separate list in sync. In my current case, they’re run-time-only objects, so they don’t need to be serialised (so it’s handy that they just disappear when saving), and it’s easy for me to just stick’em’in when loading it back in.
Here is the code I’ve been using for the job…
template <class ObjectType>
class DynamicObjectWrapper : public DynamicObject
{
public:
typedef ReferenceCountedObjectPtr<DynamicObjectWrapper<ObjectType>> Ptr;
DynamicObjectWrapper(ObjectType* objectToWrap)
: wrappedObject (objectToWrap)
{
}
virtual ~DynamicObjectWrapper()
{
}
static Ptr getFromValueTree (const ValueTree& node, const Identifier& propName)
{
DynamicObject* baseObject = node[propName].getObject();
if (baseObject)
{
DynamicObjectWrapper<ObjectType>* obj = dynamic_cast<DynamicObjectWrapper<ObjectType>*>(baseObject);
return obj;
}
return 0;
}
static ObjectType* getWrappedObjectFromValueTree (const ValueTree& node, const Identifier& propName)
{
Ptr p = getFromValueTree (node, propName);
if (p.getObject())
{
return p->getWrappedObject();
}
return 0;
}
ObjectType* getWrappedObject ()
{
return wrappedObject;
}
private:
ScopedPointer<ObjectType> wrappedObject;
};
… so, in my example case, I have a typedef DynamicObjectWrapper WrappedNameRegister, which I use when my NameRegister lives inside a node.
NOW THE QUESTION IS: Should I be ashamed? Is this ‘Bad’?