make Rec::Mutator as such diff mutable

this adds kind of an extension point to diff::Record<GenNode>::Mutator,
which is then actually defined (implemented) within the diff framework.

This allows the TreeDiffTraits automatically to use this function
to get a TreeMutator for a given Rec::Mutator. Which in turn allows
the generic version of DiffApplicator automatically to attach and
bind to a Record<GenNode>

together this allows us to ditch the explicit specialisation
and dedicated, hand-written implementation of DiffApplication
to GenNode in favour of using the TreeMutator and friends.
This commit is contained in:
Fischlurch 2016-09-05 02:25:07 +02:00
parent ebb3ccb589
commit 840d9e4397
5 changed files with 54 additions and 21 deletions

View file

@ -782,6 +782,17 @@ namespace diff{
}
/* === Extension point to apply a tree-diff === */
/** implementation is provided by the "diff framework"
* @see tree-mutator-gen-node-binding.hpp
* @see tree-diff.cpp (implementation)
*/
template<>
void MakeRec::buildMutator (BufferHandle buff);
/* === Specialisation for handling of attributes in Record<GenNode> === */
template<>

View file

@ -105,6 +105,11 @@
namespace lib {
template<class BA>
class PlantingHandle;
namespace diff{
namespace error = lumiera::error;
@ -112,6 +117,8 @@ namespace diff{
using util::isnil;
using std::string;
class TreeMutator;
template<typename VAL>
struct RecordSetup;
@ -491,7 +498,25 @@ namespace diff{
return *this;
}
/* === low-level access (for diff application === */
/* === low-level access (for diff application) === */
using BufferHandle = PlantingHandle<TreeMutator>;
/** attachment point to receive and apply tree-diff changes.
* The actual implementation needs to be provided for concrete Record payload types;
* in case of Record<GenNode>, a default implementation for this feature is provided by the
* "diff framework", which offers a preconfigured binding to create a TreeMutator implementation,
* which can then be used for a DiffApplicator. This way, a Rec::Mutator can receive diff messages
* to reorder and reshape the contents.
* @param BufferHandle pointing to an (implementation provided) storage location, where this
* function is expected to construct a suitable TreeMutator, linked to the internals
* of this Record::Mutator.
* @see lib::diff::mutatorBinding()
* @see lib::diff::DiffApplicationStrategy
* @see tree-diff-application.hpp
* @see DiffTreeApplication_test usage example
*/
void buildMutator (BufferHandle);
auto
exposeToDiff()

View file

@ -63,6 +63,21 @@ namespace diff{
using std::swap;
/** @internal possibly recursive invocation to build a TreeMutator binding
* to an "object" / scope /child node. This function is invoked when creating
* a DiffApplicator<Rec::Mutator>, and it is then invoked recursively, when
* the top level TreeMutator enters a nested scope (child node).
*/
template<>
void
Record<GenNode>::Mutator::buildMutator (BufferHandle buff)
{
buff.create (
TreeMutator::build()
.attach (*this));
}
/* == Forwarding: error handling == */

View file

@ -548,9 +548,6 @@ namespace diff{
};
/** @internal forward declaration for recursive mutator builder call */
void buildNestedMutator(Rec& nestedScope, TreeMutator::Handle buff);
/** standard configuration to deal with GenNode collections.
* @see tree-mutator-gen-node-binding.hpp */
template<>
@ -579,7 +576,8 @@ namespace diff{
if (target.idi == subID // require match on already existing child object
and target.data.isNested())
{
buildNestedMutator(target.data.get<Rec>(), buff);
mutateInPlace (target.data.get<Rec>())
.buildMutator(buff);
return true;
}
else

View file

@ -163,22 +163,6 @@ namespace diff{
return filterObjectTypeAttribute(targetTree, move(rawBinding));
}
/** @internal recursive invocation to build a binding
* to a nested scope (child node). This function is invoked
* for the `buildChildMutator` case from _DefaultBinding<GenNode>.
* But the _definition_ can only given here, after the preceding
* definition of Builder<PAR>::attach has worked out the resulting
* return type (which is just a nested DSL builder object)
*/
inline void
buildNestedMutator(Rec& nestedScope, TreeMutator::Handle buff)
{
buff.create (
TreeMutator::build()
.attach (mutateInPlace (nestedScope)));
}
}//(END)Mutator-Builder decorator components...