From 840d9e4397b7f69fd7af27476615d07e8ac39aba Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 5 Sep 2016 02:25:07 +0200 Subject: [PATCH] make Rec::Mutator as such diff mutable this adds kind of an extension point to diff::Record::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 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. --- src/lib/diff/gen-node.hpp | 11 ++++++++ src/lib/diff/record.hpp | 27 ++++++++++++++++++- src/lib/diff/tree-diff-mutator-binding.cpp | 15 +++++++++++ .../diff/tree-mutator-collection-binding.hpp | 6 ++--- .../diff/tree-mutator-gen-node-binding.hpp | 16 ----------- 5 files changed, 54 insertions(+), 21 deletions(-) diff --git a/src/lib/diff/gen-node.hpp b/src/lib/diff/gen-node.hpp index dfe20a2e6..19e3abcd5 100644 --- a/src/lib/diff/gen-node.hpp +++ b/src/lib/diff/gen-node.hpp @@ -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 === */ template<> diff --git a/src/lib/diff/record.hpp b/src/lib/diff/record.hpp index bd38dccd4..add3dd3e6 100644 --- a/src/lib/diff/record.hpp +++ b/src/lib/diff/record.hpp @@ -105,6 +105,11 @@ namespace lib { + + template + class PlantingHandle; + + namespace diff{ namespace error = lumiera::error; @@ -112,6 +117,8 @@ namespace diff{ using util::isnil; using std::string; + class TreeMutator; + template 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; + + /** 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, 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() diff --git a/src/lib/diff/tree-diff-mutator-binding.cpp b/src/lib/diff/tree-diff-mutator-binding.cpp index 123244b9f..4d6e37db9 100644 --- a/src/lib/diff/tree-diff-mutator-binding.cpp +++ b/src/lib/diff/tree-diff-mutator-binding.cpp @@ -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, and it is then invoked recursively, when + * the top level TreeMutator enters a nested scope (child node). + */ + template<> + void + Record::Mutator::buildMutator (BufferHandle buff) + { + buff.create ( + TreeMutator::build() + .attach (*this)); + } + + /* == Forwarding: error handling == */ diff --git a/src/lib/diff/tree-mutator-collection-binding.hpp b/src/lib/diff/tree-mutator-collection-binding.hpp index 1eaa6ff44..d169f6174 100644 --- a/src/lib/diff/tree-mutator-collection-binding.hpp +++ b/src/lib/diff/tree-mutator-collection-binding.hpp @@ -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(), buff); + mutateInPlace (target.data.get()) + .buildMutator(buff); return true; } else diff --git a/src/lib/diff/tree-mutator-gen-node-binding.hpp b/src/lib/diff/tree-mutator-gen-node-binding.hpp index 264431be9..914c23aed 100644 --- a/src/lib/diff/tree-mutator-gen-node-binding.hpp +++ b/src/lib/diff/tree-mutator-gen-node-binding.hpp @@ -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. - * But the _definition_ can only given here, after the preceding - * definition of Builder::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...