This is quite a big thing here, so I’ve included a very simplistic (and useless) example in the code (you can use the ‘new jucer’ project to generate suitable IDE project files).
Download example: ValueGroup_v02.zip
At it’s simplest level, a ValueGroup is simply a specialised container for holding a collection of Value objects by Identifier. It has a Listener class which allows you to easily be notified if any of the Values change.
However, it also has a number of other features, and there are a number of classes that provide additional functionality.
One feature is that each Value has an associated ValueTree ‘info’ node, which can be used as a descriptor. This can hold any kind of information your model might find useful (in particular when it comes to presenting a Value on a user interface).
In addition to that, there is a ValueGroup::Template class, which is effectively the same except it doesn’t hold any Values. This might sound somewhat limited in use (especially if you’re thinking that a ValueGroup is just an alternative to an array), but it has some great power when coupled with some other classes…
A ‘ValueReader’ is an object which can create a Value instance to represent some specific property/attribute of a given source object.
One important thing to remember about the ‘Value’ class is that it is an abstraction of some shared ValueSource object (which in turn wraps some other data). While it’s most commonly used with ValueTrees, it can be used to interface with any kind of source data. As such, the ValueReader base is templated in order to specify the type of data your subclasses can interface with. I’ve included a couple of example ValueTree value readers to illustrate what they can achieve; each one takes a given ValueTree node and returns a Value representing some information from it.
A ValueReader instance is designed to be stored as a property within an info node of a ValueGroup::Template. The ValueReader base provides a static function which can process an through a ValueGroup::Template to create a concrete, fully-hooked-up ValueGroup full of Values. These can then be used in any manner you like.
ValueGroups (and templates) are actually wrapped ValueTrees. They could have been done a different way, but this way meant that it would automatically work in the ‘pass-by-value’ reference-counted magical manner that ValueTrees do. As such, you can pass them around all over the place; the value descriptors exist in one place and are shared across to any groups that use them.
There’s also a ‘ValueInfo’ class, which wraps a ValueTree to provide some useful functionality for creating a default type of value info node. It’s not essential (as an info node is purely and publicly a ValueTree), but it’s a handy timesaver.
Soon, I’ll post the next part of this, where it’ll become more clear how this can be useful. There’s a small example in the code already (ValueGroupOverviewComponent), but it’s not particularly glamorous by itself. This simply takes a ValueGroup and displays all the Values upon itself. Their appearance can be influenced by adding specific properties to the info nodes.