![]() |
cello
JUCE ValueTrees for Humans
|
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
MAKE_VALUE_MEMBER macro now creates a static juce::Identifer that's used by all instances of the class to instantiate that member instead of re-converting from a string each time. Should be faster, and use the Identifier objects as they're intended to be used.CACHED_VALUE(name, value) macro to simplify creating cached value members for cello::Value objects.get() method to Value<T>::Cached for easier access to the cached value (e.g., you can use it to initialize an auto variable).cello::Objects in different threads via the new cello::SyncController class, which manages a pair of Sync objects and prevents feedback loops during updates.SyncController for performing updates: performNextUpdate and performAllUpdates for a given thread.Value<T>::onSet() callable. This now returns std::optional<T>; if this callable returns std::nullopt, the Value will not be modified, so you can ignore set calls that are invalid, or always return nullopt from your set validator to treat the Value as if it were const.PropertyChangeFn changed from juce::Identifier to const juce::Identifier&, which it always should have been.Value arithmetic operators by replacing noisy static_cast calls with the recently added Value::get() method that accomplishes the same thing.IpcClient to implement startUpdate and endUpdate for better state management during IPC sync.get() method to value, simplfying accessing the underlying data of a Value in its correct compile-time type.Object::wasWrapped() and Object::wasInitialized() methods.Object::getTypeName() for convenience.Object::toXmlString() for convenience.Object::findOne() method to search for and return a single child tree from an object.returnFirstFound to Query::search, used to implement the above.cello::Sync: Perform thread-safe Object updates using the juce::ValueTreeSynchroniser class. The basic approach is that we rely on a pair of cello::Objects, each of which is only accessed by a single thread. A separate cello::Sync object (or pair of them if bidirectional sync is needed) watches for changes and communicates those deltas across the thread boundary where they're applied in a thread-safe manner to the other object/tree.cello::IpcClient (and related): Connect cello::Objects in separate processes using TCP or Named Pipe-based interprocess communications. This uses a similar approach, but communicates the deltas across process boundaries using the JUCE interprocess communication API.Object by reference.type parameter passed to cello::Object constructors has been changed from juce::Identifier& to juce::String&.PropertyUpdateFn alias moved from the Object class into the top-level Cello namespace (defined in the cello_update_source.h header)Value::onPropertyChange() to simplify subscribing to value objects that are public; instead of doing e.g. myObject.onPropertyChange (myVal, callback) you can just call myVal.onPropertyChange(callback).cello::Value<T>::Cached class to store the last updated state of a Value object to make it usable without requiring a ValueTree lookup and validation each time it's needed.creationType bug on re-wrapping a ValueTree.Object:getattrObject::save now ensures that its file is created before attempting to save.Object::save returns a juce::Result instead of bool, and will indicate the reason for a failure in that return value.cello::Query class and updates to cello::Object to perform database-like queries and in-place updating of child objects. See the "Database / Query" section of the README document.Original release.