![]() |
cello
JUCE ValueTrees for Humans
|
Public Types | |
enum class | FileFormat { xml , binary , zipped } |
enum class | CreationType { initialized , wrapped } |
Public Member Functions | |
Object (const juce::String &type, const Object *state) | |
Construct a new cello::Object object, which will attempt to initialize from the 'state' parameter. If 'state' contains a ValueTree of the requested type, we'll use that as our store. | |
Object (const juce::String &type, const Object &state) | |
Construct a new Object, initializing from the state argument. Follows the same descent logic used in the above constructor. | |
Object (const juce::String &type, juce::ValueTree tree) | |
Construct a new Object from a raw juce ValueTree. Its behavior mimics that of the ctor that accepts a pointer to object, attempting to either: | |
Object (const juce::String &type, juce::File file, FileFormat format=FileFormat::xml) | |
Construct a new Object by attempting to load it from a file on disk. You can test whether this succeeded by checking the return value of getCreationType() – if its value is CreationType::initialized , the load from disk failed, and this instance was default-initialized. | |
Object (const Object &rhs) | |
Construct a new Object object as a copy of an existing one. We register as a listener, but this new copy does not have any callbacks registered. Both objects will point at the same shared value tree. | |
CreationType | wrap (const Object &other) |
Wrap another Object's tree after this object is created. | |
Object & | operator= (const Object &rhs) |
set this object to use a different Object's value tree, which we will begin listening to. Our valueTreeRedirected callback should be executed. | |
~Object () override | |
Destroy the Object object The important thing done here is to remove ourselves as a listener to the value tree we're attached to. | |
bool | operator== (const juce::ValueTree &rhs) const noexcept |
test for true equivalence: does this object point to the same underlying tree as the tree on the right hand side? Note that because cello::Object has operator juce::ValueTree , you can pass a reference to Object as the rhs and it will work correctly. | |
bool | operator!= (const juce::ValueTree &rhs) const noexcept |
juce::Identifier | getType () const |
Get the type of this object as a juce::Identifier. | |
juce::String | getTypeName () const |
Get the type of this object as a string. | |
juce::String | toXmlString (const juce::XmlElement::TextFormat &format={}) const |
Generate a string representation of this object's tree. | |
CreationType | getCreationType () const |
Determine how this object was created, which will be one of: | |
bool | wasWrapped () const |
utility method to test the creation type as a bool. | |
bool | wasInitialized () const |
utility method to test the creation type as a bool. | |
operator juce::ValueTree () const | |
Get the ValueTree we're using as our data store. | |
juce::ValueTree | clone (bool deep) const |
Make and return a copy of our underlying value tree. | |
void | update (const juce::MemoryBlock &updateBlock) |
Apply delta/update generated by the juce::ValueTreeSynchroniser class; this is used in the sync and ipc implementations. | |
void | excludeListener (juce::ValueTree::Listener *listener) |
A listener to exclude from property change updates. | |
juce::ValueTree::Listener * | getExcludedListener () const |
Get a pointer to the listener to exclude from property change updates. | |
Database functionality | |
juce::ValueTree | find (const cello::Query &query, bool deep=false) |
Perform a query against the children of this Object, returning a new ValueTree containing zero or more copies of child trees that match the query, possibly sorted into a different order than they exist in this tree. | |
juce::ValueTree | findOne (const cello::Query &query, bool deep=false) |
Perform a query against the children of this object, returning a copy of the first child found that meets the predicates in the query object, or an empty tree if none is found. | |
bool | upsert (const Object *object, const juce::Identifier &key, bool deep=false) |
Update or insert a child object (concept borrowed from MongoDB) Looks for a child with a 'key' value that matches the one found in the object we've been passed. If a match is found, we update the entry in place (update). If no match is found, we append a copy of object to our children. | |
void | upsertAll (const Object *parent, const juce::Identifier &key, bool deep=false) |
Perform an upsert using each of the children of the parent being passed. Common workflow here: | |
Undo/redo functionality | |
void | setUndoManager (juce::UndoManager *undo) |
Set the undo manager to use in this object (and others created from it). | |
juce::UndoManager * | getUndoManager () const |
Get the current undo manager; only useful to this object's Value objects and when creating other Objects to wrap our subtrees. | |
bool | canUndo () const |
Test whether this object/tree has anything that can be undone. | |
bool | undo () |
Attempt to undo the last transaction. | |
bool | canRedo () const |
Test whether this object/tree has anything that can be redone. | |
bool | redo () |
Attempt to redo the last transaction. | |
void | clearUndoHistory () |
reset the undo manager | |
Pythonesque access | |
We use names (ending in | |
template<typename T> | |
T | getattr (const juce::Identifier &attr, const T &defaultVal) const |
Get a property value from this object, or default if it doesn't have a property with that name. | |
bool | hasattr (const juce::Identifier &attr) const |
test the object to see if it has an attribute with this id. | |
template<typename T> | |
Object & | setattr (const juce::Identifier &attr, const T &attrVal) |
Set a new value for the specified attribute/property. We return a reference to this object so that setattr calls may be chained. | |
void | delattr (const juce::Identifier &attr) |
Remove the specified property from this object. | |
![]() | |
void | forceUpdate (bool shouldForceUpdate) |
If passed true, any call that sets any Value property on this Object will result in a property change update callback being executed. Default (false) behavior only performs this callback when the underlying value is changed. | |
bool | shouldForceUpdate () const |
Protected Attributes | |
juce::ValueTree | data |
The tree where our data lives. | |
juce::UndoManager * | undoManager { nullptr } |
The undo manager to use for set() operations. | |
CreationType | creationType { CreationType::wrapped } |
Remember how this Object was created. | |
juce::ValueTree::Listener * | excludedListener { nullptr } |
a listener to not update when properties change. | |
bool | doForceUpdates { false } |
Child Operations | |
using | Iterator = juce::ValueTree::Iterator |
Iterator | begin () |
Iterator | end () |
juce::ValueTree | operator[] (int index) const |
return a child tree of this object by its index. NOTE that it does not return an object; to work with this data in its cello::Object form, you'll need to use this tree to create a new one, probably testing its type to make sure you're creating the correct Object type from it. | |
int | getNumChildren () const |
Check how many children this object has. | |
void | append (Object *object) |
Add a new child object to the end of our child object list,. | |
void | insert (Object *object, int index) |
add a new child object at a specific index in the list. | |
Object * | remove (Object *object) |
Attempt to remove a child object from this. | |
juce::ValueTree | remove (int index) |
remove a child by its index. | |
void | move (int fromIndex, int toIndex) |
Change the position of one of this object's children. | |
template<typename Comparator> | |
void | sort (Comparator &comp, bool stableSort) |
Sort this object's children using the provided comparison object. | |
Callbacks | |
using | ChildUpdateFn = std::function<void (juce::ValueTree& child, int oldIndex, int newIndex)> |
using | SelfUpdateFn = std::function<void (void)> |
ChildUpdateFn | onChildAdded |
ChildUpdateFn | onChildRemoved |
ChildUpdateFn | onChildMoved |
SelfUpdateFn | onParentChanged |
SelfUpdateFn | onTreeRedirected |
void | onPropertyChange (juce::Identifier id, PropertyUpdateFn callback) |
Install (or clear) a function to be called when one of this Object's properties changes. A cello extension to this mechanism is that you can pass in the type id of this tree, and you'll receive a callback on that key when any of the other properties that don't have a handler have changed. | |
void | onPropertyChange (PropertyUpdateFn callback) |
install or clear a generic callback that will be called when any property in the object changes. The identifier of the property that changed will be passed to the callback. | |
void | onPropertyChange (const ValueBase &val, PropertyUpdateFn callback) |
register a property change callback by passing in a reference to a Value object instead of its id. | |
File operations | |
save/load objects to/from disk. | |
juce::Result | save (juce::File file, FileFormat format=FileFormat::xml) const |
Save the object tree to disk. | |
static juce::ValueTree | load (juce::File file, FileFormat format=FileFormat::xml) |
Reload data from disk. Used in the ctor that accepts file name and format. | |
cello::Object::Object | ( | const juce::String & | type, |
const Object * | state ) |
Construct a new cello::Object object, which will attempt to initialize from the 'state' parameter. If 'state' contains a ValueTree of the requested type, we'll use that as our store.
Otherwise, we look for a child of our type: if found, we use that as our data. if not found, we create and (default) intialize a new tree of our type and add it as a child to the tree pointed to by state. If state is nullptr, we create and default-initialize a new tree object.
We register as a listener to whatever value tree we just found or created.
type | |
state | pointer to a cello::Object; pass nullptr to default initialize. |
cello::Object::Object | ( | const juce::String & | type, |
const Object & | state ) |
Construct a new Object, initializing from the state
argument. Follows the same descent logic used in the above constructor.
type | |
state |
cello::Object::Object | ( | const juce::String & | type, |
juce::ValueTree | tree ) |
Construct a new Object from a raw juce ValueTree. Its behavior mimics that of the ctor that accepts a pointer to object, attempting to either:
type | |
tree |
cello::Object::Object | ( | const juce::String & | type, |
juce::File | file, | ||
Object::FileFormat | format = FileFormat::xml ) |
Construct a new Object by attempting to load it from a file on disk. You can test whether this succeeded by checking the return value of getCreationType()
– if its value is CreationType::initialized
, the load from disk failed, and this instance was default-initialized.
type | |
file | |
format |
cello::Object::Object | ( | const Object & | rhs | ) |
void cello::Object::append | ( | Object * | object | ) |
Add a new child object to the end of our child object list,.
object |
bool cello::Object::canRedo | ( | ) | const |
Test whether this object/tree has anything that can be redone.
bool cello::Object::canUndo | ( | ) | const |
Test whether this object/tree has anything that can be undone.
juce::ValueTree cello::Object::clone | ( | bool | deep | ) | const |
Make and return a copy of our underlying value tree.
deep | Include children? |
void cello::Object::delattr | ( | const juce::Identifier & | attr | ) |
Remove the specified property from this object.
attr |
|
inline |
A listener to exclude from property change updates.
listener |
juce::ValueTree cello::Object::find | ( | const cello::Query & | query, |
bool | deep = false ) |
Perform a query against the children of this Object, returning a new ValueTree containing zero or more copies of child trees that match the query, possibly sorted into a different order than they exist in this tree.
query | Query object that defines the search/sort criteria |
deep | if true, also copy sub-items from object. |
juce::ValueTree cello::Object::findOne | ( | const cello::Query & | query, |
bool | deep = false ) |
Perform a query against the children of this object, returning a copy of the first child found that meets the predicates in the query object, or an empty tree if none is found.
query | Query object that defines the search/sort criteria |
deep | if true, also copy sub-items from object. |
|
inline |
Get a property value from this object, or default if it doesn't have a property with that name.
T |
attr | |
defaultVal |
|
inline |
Determine how this object was created, which will be one of:
It might be an error in your application to expect one or the other and not find it at runtime.
|
inline |
Get a pointer to the listener to exclude from property change updates.
int cello::Object::getNumChildren | ( | ) | const |
Check how many children this object has.
|
inline |
Get the type of this object as a juce::Identifier.
|
inline |
Get the type of this object as a string.
juce::UndoManager * cello::Object::getUndoManager | ( | ) | const |
Get the current undo manager; only useful to this object's Value objects and when creating other Objects to wrap our subtrees.
bool cello::Object::hasattr | ( | const juce::Identifier & | attr | ) | const |
test the object to see if it has an attribute with this id.
attr |
void cello::Object::insert | ( | Object * | object, |
int | index ) |
add a new child object at a specific index in the list.
object | |
index |
|
static |
Reload data from disk. Used in the ctor that accepts file name and format.
file | |
format | one of (xml, binary, zipped) |
void cello::Object::move | ( | int | fromIndex, |
int | toIndex ) |
Change the position of one of this object's children.
fromIndex | |
toIndex |
void cello::Object::onPropertyChange | ( | const ValueBase & | val, |
PropertyUpdateFn | callback ) |
register a property change callback by passing in a reference to a Value object instead of its id.
val | |
callback |
void cello::Object::onPropertyChange | ( | juce::Identifier | id, |
PropertyUpdateFn | callback ) |
Install (or clear) a function to be called when one of this Object's properties changes. A cello extension to this mechanism is that you can pass in the type id of this tree, and you'll receive a callback on that key when any of the other properties that don't have a handler have changed.
id | the ID of the property that has changed. |
callback | function to call on update. |
|
inline |
install or clear a generic callback that will be called when any property in the object changes. The identifier of the property that changed will be passed to the callback.
callback |
|
inline |
Get the ValueTree we're using as our data store.
|
inlinenoexcept |
test for true equivalence: does this object point to the same underlying tree as the tree on the right hand side? Note that because cello::Object has operator juce::ValueTree
, you can pass a reference to Object as the rhs and it will work correctly.
rhs |
juce::ValueTree cello::Object::operator[] | ( | int | index | ) | const |
return a child tree of this object by its index. NOTE that it does not return an object; to work with this data in its cello::Object form, you'll need to use this tree to create a new one, probably testing its type to make sure you're creating the correct Object type from it.
index |
bool cello::Object::redo | ( | ) |
Attempt to redo the last transaction.
juce::ValueTree cello::Object::remove | ( | int | index | ) |
remove a child by its index.
index |
Attempt to remove a child object from this.
object | Object containing sub-tree to remove |
juce::Result cello::Object::save | ( | juce::File | file, |
FileFormat | format = FileFormat::xml ) const |
Save the object tree to disk.
file | |
format | one of (xml, binary, zipped) |
|
inline |
Set a new value for the specified attribute/property. We return a reference to this object so that setattr calls may be chained.
T |
attr | |
attrVal |
void cello::Object::setUndoManager | ( | juce::UndoManager * | undo | ) |
Set the undo manager to use in this object (and others created from it).
undo |
void cello::Object::sort | ( | Comparator & | comp, |
bool | stableSort ) |
Sort this object's children using the provided comparison object.
The comp
object must contain a method that uses the signature: int compareElements (const ValueTree& first, const ValueTree& second)
and returns
comp | |
stableSort | true to keep equivalent items in the same order after sorting. |
|
inline |
Generate a string representation of this object's tree.
format | specifies details of the output. |
bool cello::Object::undo | ( | ) |
Attempt to undo the last transaction.
void cello::Object::update | ( | const juce::MemoryBlock & | updateBlock | ) |
Apply delta/update generated by the juce::ValueTreeSynchroniser class; this is used in the sync and ipc implementations.
updateBlock | Binary data to apply to this object. |
bool cello::Object::upsert | ( | const Object * | object, |
const juce::Identifier & | key, | ||
bool | deep = false ) |
Update or insert a child object (concept borrowed from MongoDB) Looks for a child with a 'key' value that matches the one found in the object we've been passed. If a match is found, we update the entry in place (update). If no match is found, we append a copy of object
to our children.
object | Object with data to update or add |
key | property name to use to match the two entries |
deep | if true, also copy sub-items from object. |
void cello::Object::upsertAll | ( | const Object * | parent, |
const juce::Identifier & | key, | ||
bool | deep = false ) |
Perform an upsert using each of the children of the parent being passed. Common workflow here:
parent | object with children to use as update sources |
key | key to match children together |
deep | copy subtrees as well? |
|
inline |
utility method to test the creation type as a bool.
|
inline |
utility method to test the creation type as a bool.
Object::CreationType cello::Object::wrap | ( | const Object & | other | ) |
Wrap another Object's tree after this object is created.
other |
|
protected |
should we send property change notifications even if a property doesn't change?