20#include "JuceHeader.h"
22#include "cello_object.h"
42 wrap (type,
static_cast<juce::ValueTree
> (tree));
45Object::Object (
const juce::String& type, juce::File file, Object::FileFormat format)
55 data.addListener (
this);
60 data.removeListener (
this);
61 const auto result {
wrap (
getType ().toString (), other) };
76 data.removeListener (
this);
81 auto cloneTree { juce::ValueTree {
getType () } };
83 cloneTree.copyPropertiesAndChildrenFrom (
data,
nullptr);
85 cloneTree.copyPropertiesFrom (
data,
nullptr);
91 juce::ValueTreeSynchroniser::applyChange (
data, updateBlock.getData (), updateBlock.getSize (),
getUndoManager ());
109 const auto val {
object->data[key] };
111 auto existingItem {
data.getChildWithProperty (key, val) };
112 if (existingItem.isValid ())
116 existingItem.copyPropertiesAndChildrenFrom (*
object,
getUndoManager ());
128 juce::ValueTree parentTree { *parent };
129 for (
const auto& child : parentTree)
131 const auto type { child.getType () };
132 Object item { type.toString (), child };
134 if (!
upsert (&item, key, deep))
147 return undoMgr->canUndo ();
154 return undoMgr->undo ();
161 return undoMgr->canRedo ();
168 return undoMgr->redo ();
175 undoMgr->clearUndoHistory ();
180 return data.getNumChildren ();
185 if (index < 0 || index >=
data.getNumChildren ())
188 return data.getChild (index);
206 juce::ValueTree newChild { *
object };
207 juce::ValueTree parent { newChild.getParent () };
209 if (parent.isValid ())
228 auto removedTree {
remove (
data.indexOf (*
object)) };
229 return removedTree.isValid () ? object :
nullptr;
234 auto treeToRemove {
data.getChild (index) };
235 if (treeToRemove.isValid ())
245template <
typename Comparator>
void Object::sort (Comparator& comp,
bool stableSort)
258 for (
auto& updater : propertyUpdaters)
260 if (updater.id ==
id)
262 updater.fn = callback;
267 propertyUpdaters.emplace_back (
id, callback);
277 return data.hasProperty (attr);
287 if (format == Object::FileFormat::xml)
289 const auto xmlText { file.loadFileAsString () };
290 return juce::ValueTree::fromXml (xmlText);
294 juce::MemoryBlock mb;
295 if (!file.loadFileAsData (mb))
300 if (format == Object::FileFormat::binary)
301 return juce::ValueTree::readFromData (mb.getData (), mb.getSize ());
302 else if (format == Object::FileFormat::zipped)
303 return juce::ValueTree::readFromGZIPData (mb.getData (), mb.getSize ());
312 if (format == FileFormat::xml)
314 auto res { file.create () };
317 if (file.replaceWithText (
data.toXmlString ()))
318 return juce::Result::ok ();
319 res = juce::Result::fail (
"Error writing to " + file.getFullPathName ());
324 juce::FileOutputStream fos { file };
325 if (!fos.openedOk ())
328 return juce::Result::fail (
"Unable to open " + file.getFullPathName () +
" for writing");
331 if (format == FileFormat::binary)
333 data.writeToStream (fos);
334 return juce::Result::ok ();
337 else if (format == FileFormat::zipped)
339 juce::GZIPCompressorOutputStream zipper { fos };
340 data.writeToStream (zipper);
341 return juce::Result::ok ();
346 return juce::Result::fail (
"Unknown file format");
349Object::CreationType
Object::wrap (
const juce::String& type, juce::ValueTree tree)
360 data.addListener (
this);
364void Object::valueTreePropertyChanged (juce::ValueTree& treeWhosePropertyHasChanged,
const juce::Identifier& property)
366 if (treeWhosePropertyHasChanged !=
data)
370 auto callUpdaterForProperty = [
this] (
const juce::Identifier& key,
const juce::Identifier& prop) ->
bool
372 for (
const auto& updater : propertyUpdaters)
374 if (updater.id == key)
376 if (updater.fn !=
nullptr)
385 if (callUpdaterForProperty (property, property))
388 callUpdaterForProperty (
getType (), property);
391void Object::valueTreeChildAdded (juce::ValueTree& parentTree, juce::ValueTree& childTree)
393 if (parentTree ==
data && onChildAdded !=
nullptr)
394 onChildAdded (childTree, -1,
data.indexOf (childTree));
397void Object::valueTreeChildRemoved (juce::ValueTree& parentTree, juce::ValueTree& childTree,
int index)
399 if (parentTree ==
data && onChildRemoved !=
nullptr)
400 onChildRemoved (childTree, index, -1);
403void Object::valueTreeChildOrderChanged (juce::ValueTree& parentTree,
int oldIndex,
int newIndex)
405 if (parentTree ==
data && onChildMoved !=
nullptr)
407 auto childTree {
data.getChild (newIndex) };
408 onChildMoved (childTree, oldIndex, newIndex);
412void Object::valueTreeParentChanged (juce::ValueTree& tree)
414 if (tree ==
data && onParentChanged !=
nullptr)
418void Object::valueTreeRedirected (juce::ValueTree& tree)
420 if (tree ==
data && onTreeRedirected !=
nullptr)
427#include "test/test_cello_object.inl"
void move(int fromIndex, int toIndex)
Change the position of one of this object's children.
Definition cello_object.cpp:240
void setUndoManager(juce::UndoManager *undo)
Set the undo manager to use in this object (and others created from it).
Definition cello_object.cpp:139
void sort(Comparator &comp, bool stableSort)
Sort this object's children using the provided comparison object.
Definition cello_object.cpp:245
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 ...
Definition cello_object.cpp:104
void onPropertyChange(juce::Identifier id, PropertyUpdateFn callback)
Install (or clear) a function to be called when one of this Object's properties changes....
Definition cello_object.cpp:255
~Object() override
Destroy the Object object The important thing done here is to remove ourselves as a listener to the v...
Definition cello_object.cpp:74
juce::ValueTree data
The tree where our data lives.
Definition cello_object.h:637
CreationType wrap(const Object &other)
Wrap another Object's tree after this object is created.
Definition cello_object.cpp:58
Object(const juce::String &type, const Object *state)
Construct a new cello::Object object, which will attempt to initialize from the 'state' parameter....
Definition cello_object.cpp:27
juce::Result save(juce::File file, FileFormat format=FileFormat::xml) const
Save the object tree to disk.
Definition cello_object.cpp:310
bool redo()
Attempt to redo the last transaction.
Definition cello_object.cpp:165
bool hasattr(const juce::Identifier &attr) const
test the object to see if it has an attribute with this id.
Definition cello_object.cpp:275
juce::ValueTree clone(bool deep) const
Make and return a copy of our underlying value tree.
Definition cello_object.cpp:79
bool canUndo() const
Test whether this object/tree has anything that can be undone.
Definition cello_object.cpp:144
void delattr(const juce::Identifier &attr)
Remove the specified property from this object.
Definition cello_object.cpp:280
int getNumChildren() const
Check how many children this object has.
Definition cello_object.cpp:178
bool canRedo() const
Test whether this object/tree has anything that can be redone.
Definition cello_object.cpp:158
juce::UndoManager * undoManager
The undo manager to use for set() operations.
Definition cello_object.h:640
bool undo()
Attempt to undo the last transaction.
Definition cello_object.cpp:151
juce::Identifier getType() const
Get the type of this object as a juce::Identifier.
Definition cello_object.h:154
CreationType creationType
Remember how this Object was created.
Definition cello_object.h:643
juce::UndoManager * getUndoManager() const
Get the current undo manager; only useful to this object's Value objects and when creating other Obje...
Definition cello_object.cpp:250
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 mor...
Definition cello_object.cpp:94
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 m...
Definition cello_object.cpp:99
operator juce::ValueTree() const
Get the ValueTree we're using as our data store.
Definition cello_object.h:206
Object * remove(Object *object)
Attempt to remove a child object from this.
Definition cello_object.cpp:221
void clearUndoHistory()
reset the undo manager
Definition cello_object.cpp:172
void update(const juce::MemoryBlock &updateBlock)
Apply delta/update generated by the juce::ValueTreeSynchroniser class; this is used in the sync and i...
Definition cello_object.cpp:89
void append(Object *object)
Add a new child object to the end of our child object list,.
Definition cello_object.cpp:191
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.
Definition cello_object.cpp:285
Object & operator=(const Object &rhs)
set this object to use a different Object's value tree, which we will begin listening to....
Definition cello_object.cpp:66
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...
Definition cello_object.cpp:183
void insert(Object *object, int index)
add a new child object at a specific index in the list.
Definition cello_object.cpp:196
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:
Definition cello_object.cpp:126
Class to navigate between subtrees that are all connected together.
Definition cello_path.h:50
@ createAll
create final tree and all intermediate trees needed to reach it.
Definition cello_path.h:67
juce::ValueTree findValueTree(juce::ValueTree &origin, SearchType searchType, juce::UndoManager *undo=nullptr)
Navigate the path from origin to a tree that is expected at the end of the current path specification...
Definition cello_path.cpp:59
@ created
performing a search created a new tree
Definition cello_path.h:74
Definition cello_query.h:28
juce::ValueTree search(juce::ValueTree tree, bool deep, bool returnFirstFound=false) const
Execute the query we're programmed for – iterate through the children of tree, returning a new tree o...
Definition cello_query.cpp:41
Definition cello_value.h:30
juce::Identifier getId() const
Definition cello_value.h:35