diff --git a/src/gui/ctrl/nexus.hpp b/src/gui/ctrl/nexus.hpp index 153c43968..0476e8770 100644 --- a/src/gui/ctrl/nexus.hpp +++ b/src/gui/ctrl/nexus.hpp @@ -125,7 +125,6 @@ namespace ctrl{ return false; else { - UNIMPLEMENTED("actually apply a diff to the target Tangible"); diff.applyTo (*entry->second); return true; } diff --git a/src/lib/diff/test-mutation-target.hpp b/src/lib/diff/test-mutation-target.hpp index 4f9f79d4d..aacfbc61d 100644 --- a/src/lib/diff/test-mutation-target.hpp +++ b/src/lib/diff/test-mutation-target.hpp @@ -369,12 +369,19 @@ namespace diff{ TestWireTap(Target& dummy, PAR&& chain) : PAR{forward (chain)} , target_(dummy) - , pos_(target_.initMutation (identify(this))) + , pos_() { } /* ==== re-Implementation of the operation API ==== */ + + virtual void + init() override + { + pos_ = target_.initMutation (identify(this)); + PAR::init(); + } /** record in the test target * that a new child element is diff --git a/src/lib/diff/tree-diff-application.hpp b/src/lib/diff/tree-diff-application.hpp index b4230cdea..8c3415d38 100644 --- a/src/lib/diff/tree-diff-application.hpp +++ b/src/lib/diff/tree-diff-application.hpp @@ -379,7 +379,7 @@ namespace diff{ using Target = typename TreeDiffTraits::Ret; Target target = mutatorBinding (subject_); - buildMutator (target); + buildMutator (target)->init(); TreeDiffMutatorBinding::scopeManger_ = &scopes_; TreeDiffMutatorBinding::treeMutator_ = &scopes_.currentScope(); REQUIRE (this->treeMutator_); diff --git a/src/lib/diff/tree-mutator-collection-binding.hpp b/src/lib/diff/tree-mutator-collection-binding.hpp index e90199089..e2c1654fc 100644 --- a/src/lib/diff/tree-mutator-collection-binding.hpp +++ b/src/lib/diff/tree-mutator-collection-binding.hpp @@ -268,7 +268,7 @@ namespace diff{ ChildCollectionMutator(BIN&& wiringClosures, PAR&& chain) : PAR(std::forward(chain)) , binding_(forward(wiringClosures)) - , pos_(binding_.initMutation()) + , pos_() { } @@ -276,6 +276,13 @@ namespace diff{ /* ==== Implementation of TreeNode operation API ==== */ + virtual void + init() override + { + pos_ = binding_.initMutation(); + PAR::init(); + } + /** fabricate a new element, based on * the given specification (GenNode), * and insert it at current position diff --git a/src/lib/diff/tree-mutator.hpp b/src/lib/diff/tree-mutator.hpp index 5c74bae99..a63b3bd1f 100644 --- a/src/lib/diff/tree-mutator.hpp +++ b/src/lib/diff/tree-mutator.hpp @@ -156,6 +156,15 @@ namespace diff{ /* ==== operation API ==== */ + /** initialisation immediately before start of diff application + * @remark allows for setup of state which is dependent on memory location, + * like e.g. iterators. Due to the invokation via Builder DSL, the + * implementation object may be moved after construction, but prior + * to invoking this hook + */ + virtual void + init() { } + virtual bool hasSrc () ////////////////////////////////////TODO questionable if we need it. Can not be sensibly implemented on multiple onion-layers! { diff --git a/tests/library/diff/tree-mutator-binding-test.cpp b/tests/library/diff/tree-mutator-binding-test.cpp index 1682d1059..0e680ac3a 100644 --- a/tests/library/diff/tree-mutator-binding-test.cpp +++ b/tests/library/diff/tree-mutator-binding-test.cpp @@ -169,6 +169,7 @@ namespace test{ auto mutator = TreeMutator::build() .attachDummy (target); + mutator.init(); CHECK (isnil (target)); CHECK (not mutator.hasSrc()); @@ -203,6 +204,7 @@ namespace test{ auto mutator2 = TreeMutator::build() .attachDummy (target); + mutator2.init(); CHECK (target.verify("attachMutator") .beforeEvent("injectNew","78:56:34.012") @@ -274,6 +276,7 @@ namespace test{ auto mutator3 = TreeMutator::build() .attachDummy (target); + mutator3.init(); // the first thing we try out is how to navigate through the sequence partially CHECK (isnil (target)); @@ -394,6 +397,8 @@ namespace test{ // --- first round: populate the collection --- + mutator1.init(); + CHECK (isnil (target)); CHECK (not mutator1.hasSrc()); @@ -448,7 +453,7 @@ namespace test{ // we have two lambdas now and thus can save on the size of one function pointer.... CHECK (sizeof(mutator1) - sizeof(mutator2) == sizeof(void*)); - + mutator2.init(); CHECK (isnil (target)); // the "visible" new content is still void CHECK (mutator2.matchSrc (ATTRIB1)); // current head element of src "matches" the given spec @@ -558,6 +563,8 @@ namespace test{ return true; })); + mutator3.init(); + CHECK (isnil (target)); CHECK (mutator3.matchSrc (ATTRIB1)); // new mutator starts out anew at the beginning CHECK (mutator3.accept_until (CHILD_T)); // fast forward behind the second-last child (CHILD_T) // accept_until @@ -696,6 +703,7 @@ namespace test{ LOG_SETTER ("gamma") gamma = val; }); + mutator1.init(); CHECK (sizeof(mutator1) <= sizeof(void*) // the TreeMutator VTable + 2 * sizeof(void*) // one closure reference for each lambda @@ -768,6 +776,8 @@ namespace test{ LOG_SETTER ("gamma") gamma = val; }); + mutator2.init(); + CHECK (sizeof(mutator2) <= sizeof(void*) // the TreeMutator VTable + 3 * sizeof(void*) // one closure reference for each lambda @@ -857,6 +867,7 @@ namespace test{ cout << "openSub()...\n" << join(delta.getLog(), "\n") <