Diff-Framework: add clean-up hook to diff-application

Our diff language requires a diff to handle the complete contents of the target.
Through this clean-up hook this is now in fact enforced.

The actual reason for adding this however was that I need to ensure
listeners are triggered
This commit is contained in:
Fischlurch 2019-12-15 15:06:04 +01:00
parent 3e1d0036ed
commit 9f3fe8a885
6 changed files with 56 additions and 2 deletions

View file

@ -270,6 +270,8 @@ namespace diff{
* target type `TAR` (1st template arg)
* @warning the actual language remains unspecified;
* it is picked from the visible context.
* @see tree-diff-application.hpp
* @see list-diff-application.hpp
*/
template<class TAR, typename SEL =void>
class DiffApplicationStrategy;
@ -307,6 +309,7 @@ namespace diff{
target_.initDiffApplication();
for ( ; diff; ++diff )
diff->applyTo(target_);
target_.completeDiffApplication();
}
};

View file

@ -171,6 +171,17 @@ namespace diff{
seq_.reserve (orig_.size() * 120 / 100); // heuristics for storage pre-allocation
pos_ = orig_.begin();
}
void
completeDiffApplication()
{
if (not end_of_target())
throw error::State(_Fmt("Not all source data consumed after diff application. "
"Element %s waiting to be consumed") % *pos_
, LERR_(DIFF_STRUCTURE));
// discard storage
orig_.clear();
}
};

View file

@ -271,6 +271,7 @@ namespace diff{
* @throws _unspecified errors_ when delegated operations fail.
* @see TreeDiffInterpreter explanation of the verbs
* @see DiffComplexApplication_test demonstration of usage
* @see [implementation of the binding functions](\ref tree-diff.cpp)
*/
class TreeDiffMutatorBinding
: public TreeDiffInterpreter
@ -384,6 +385,18 @@ namespace diff{
TreeDiffMutatorBinding::treeMutator_ = &scopes_.currentScope();
REQUIRE (this->treeMutator_);
}
void
completeDiffApplication()
{
if (not treeMutator_->completeScope())
throw error::State(_Fmt("Unsettled content remains after diff application. "
"Top level == %s") % subject_
, LERR_(DIFF_STRUCTURE));
// discard storage
treeMutator_ = nullptr;
scopes_.clear();
}
};

View file

@ -118,7 +118,7 @@ namespace diff{
throw error::State(_Fmt("Diff application floundered in nested scope %s; "
"unexpected extra elements found when diff "
"should have settled everything.") % idi.getSym()
, LUMIERA_ERROR_DIFF_CONFLICT);
, LUMIERA_ERROR_DIFF_STRUCTURE);
}
void
@ -127,7 +127,7 @@ namespace diff{
if (0 == scopeManger_->depth())
throw error::Fatal(_Fmt("Diff application floundered after leaving scope %s; "
"unbalanced nested scopes, diff attempts to pop root.") % idi.getSym()
, LUMIERA_ERROR_DIFF_CONFLICT);
, LUMIERA_ERROR_DIFF_STRUCTURE);
}

View file

@ -84,6 +84,7 @@
** @see tree-mutator-test.cpp
** @see tree-mutator-binding-test.cpp
** @see [usage for tree diff application](\ref tree-diff-application.hpp)
** especially `DiffApplicationStrategy<TAR, enable_if<TreeDiffTraits<TAR>>>` defined there
** @see diff-language.hpp
** @see DiffDetector
**

View file

@ -36283,12 +36283,38 @@
</node>
</node>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1576416522053" ID="ID_910911447" MODIFIED="1576416574835" TEXT="listener wird nicht getriggert">
<linktarget COLOR="#e03f68" DESTINATION="ID_910911447" ENDARROW="Default" ENDINCLINATION="-217;7;" ID="Arrow_ID_929225071" SOURCE="ID_159550911" STARTARROW="None" STARTINCLINATION="-2;-97;"/>
<icon BUILTIN="broken-line"/>
<node CREATED="1576416597927" ID="ID_805984773" MODIFIED="1576416619356" TEXT="ctor vom top-Level nicht aufgerufen"/>
<node CREATED="1576416620136" ID="ID_1598925580" MODIFIED="1576416632057" TEXT="denn der top-Level-TreeMutator lebt weiter"/>
<node CREATED="1576416632790" ID="ID_141285194" MODIFIED="1576416640381" TEXT="...solange der DiffApplikator lebt"/>
<node CREATED="1576416641269" ID="ID_605158809" MODIFIED="1576416645584" TEXT="ist das gut so?">
<node CREATED="1576416647561" ID="ID_486491592" MODIFIED="1576416658877" TEXT="viele Tests verwenden den Applikator mehrfach"/>
<node CREATED="1576416659587" ID="ID_791956106" MODIFIED="1576416715929" TEXT="nicht jedoch die produktive Verwendung in ctrl::Nexus::change (ID, MutationMessage&amp;&amp; diff)">
<icon BUILTIN="forward"/>
</node>
<node CREATED="1576416749566" ID="ID_1371891888" MODIFIED="1576417191286" TEXT="das k&#xf6;nnte sp&#xe4;ter auch ein Ansatzpunkt f&#xfc;r Caching sein">
<icon BUILTIN="button_cancel"/>
</node>
<node CREATED="1576417156080" ID="ID_1679161356" MODIFIED="1576417199243" TEXT="aber: jede neue Anwendung konstruiert einen neuen TreeMutator">
<icon BUILTIN="idea"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1576417208152" ID="ID_974220547" MODIFIED="1576417222583" TEXT="also braucht die Diff-Anwendung einen Abschlu&#xdf;">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1576189140651" ID="ID_835328626" MODIFIED="1576360868184" TEXT="Test">
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1576189161697" ID="ID_1786250967" MODIFIED="1576189178606" TEXT="Struktur&#xe4;nderungen triggern Listener">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1576416511260" ID="ID_159550911" MODIFIED="1576416585202" TEXT="tut noch nicht...">
<arrowlink COLOR="#e03f68" DESTINATION="ID_910911447" ENDARROW="Default" ENDINCLINATION="-217;7;" ID="Arrow_ID_929225071" STARTARROW="None" STARTINCLINATION="-2;-97;"/>
<icon BUILTIN="flag-yellow"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1576189172445" ID="ID_1803915875" MODIFIED="1576189177766" TEXT="andere &#xc4;nderungen triggern nicht">
<icon BUILTIN="flag-yellow"/>