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:
parent
ebb3ccb589
commit
840d9e4397
5 changed files with 54 additions and 21 deletions
|
|
@ -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<>
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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 == */
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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...
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue