considerations how to access the "tree mutator building closure"
this is at the core of the integration problem: how do we expose the ability of some opaque data structure to create a TreeMutator? The idea is - to use a marker/capability interface - to use template specialisation to fabricate an instance of that interface based on the given access point to the opaque data structure
This commit is contained in:
parent
61627b26a0
commit
5744244f73
5 changed files with 256 additions and 15 deletions
92
src/lib/diff/diff-mutable.hpp
Normal file
92
src/lib/diff/diff-mutable.hpp
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
DIFF-MUTABLE.hpp - interface for data structures mutable through diff message
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2016, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/** @file diff-mutable.hpp
|
||||
** Abstraction or descriptor interface for a data structure
|
||||
** exposing the ability for mutation by receiving diff messages.
|
||||
** Differences and changes on such data structures can be specified in the form
|
||||
** of a "linearised diff language". Such a diff can be represented as a sequence
|
||||
** of tokens, describing the manipulations necessary to effect the desired change.
|
||||
** While, conceptually, such a diff is drawn against a generic tree like data
|
||||
** description (actually based on diff::Record<GenNode>), with the help of a
|
||||
** customisable intermediary binding layer, it is possible to apply such diff
|
||||
** messages onto data structures otherwise not further disclosed. For this to
|
||||
** work, the target data structure itself must offer the ability to construct
|
||||
** such a suitable intermediary binding layer. This interface declares and
|
||||
** offers this ability.
|
||||
**
|
||||
** A data structure exposing this interface in one way or the other (which
|
||||
** might be through the help of an ADL bound free function) thus offers some kind
|
||||
** of closure, which, when invoked, will build a concrete TreeMutator implementation
|
||||
** into the given working buffer. Obviously, this TreeMutator is then somehow opaquely
|
||||
** wired to the data structure so to be able to invoke transforming operations on
|
||||
** this target data. Here, the TreeMutator interface defines the primitive operations
|
||||
** necessary to apply a conforming diff message onto this otherwise private data
|
||||
** structure. Based on such a setup, client code may create a DiffApplicator
|
||||
** to embody this custom TreeMutator, which in the end allows to consume
|
||||
** diff messages, thereby transforming and mutating the target data
|
||||
** structure without the need to know any internal details.
|
||||
**
|
||||
** @see diff-language.hpp
|
||||
** @see tree-diff-application.hpp
|
||||
** @see diff-virtualised-application-test.cpp
|
||||
** @see TreeMutator
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LIB_DIFF_DIFF_MUTABLE_H
|
||||
#define LIB_DIFF_DIFF_MUTABLE_H
|
||||
|
||||
|
||||
#include "lib/diff/tree-mutator.hpp"
|
||||
|
||||
|
||||
|
||||
namespace lib {
|
||||
namespace diff{
|
||||
|
||||
|
||||
/**
|
||||
* Marker or capability interface:
|
||||
* an otherwise not further disclosed data structure,
|
||||
* which can be transformed through "tree diff messages"
|
||||
*/
|
||||
class DiffMutable
|
||||
{
|
||||
public:
|
||||
virtual ~DiffMutable() { } ///< this is an interface
|
||||
|
||||
/** build a custom implementation of the TreeMutator interface,
|
||||
* suitably wired to cause appropriate changes to the opaque
|
||||
* data structure, in accordance to the semantics of the
|
||||
* tree diff language.
|
||||
* @param a buffer handle, which can be used to placement-construct
|
||||
*/
|
||||
virtual void buildMutator (TreeMutator::Handle) =0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}} // namespace lib::diff
|
||||
#endif /*LIB_DIFF_DIFF_MUTABLE_H*/
|
||||
|
|
@ -69,6 +69,7 @@
|
|||
|
||||
#include "lib/diff/tree-diff.hpp"
|
||||
#include "lib/diff/tree-mutator.hpp"
|
||||
#include "lib/diff/diff-mutable.hpp"
|
||||
#include "lib/diff/gen-node.hpp"
|
||||
#include "lib/format-string.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
|
@ -79,6 +80,31 @@
|
|||
namespace lib {
|
||||
namespace diff{
|
||||
|
||||
/* ======= derive a TreeMutator binding for a given opaque data structure ======= */
|
||||
|
||||
template<class TAR, typename SEL =void>
|
||||
struct MutatorBinding
|
||||
{
|
||||
///////////////TODO
|
||||
|
||||
operator DiffMutable& ()
|
||||
{
|
||||
UNIMPLEMENTED ("how to build and pass the closure safely");
|
||||
}
|
||||
};
|
||||
|
||||
template<class TAR>
|
||||
DiffMutable&
|
||||
mutatorBinding (TAR& subject)
|
||||
{
|
||||
UNIMPLEMENTED ("how to detect, create and pass a suitable mutator building closure");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* ======= Implementation of Tree Diff Application via TreeMutator ======= */
|
||||
|
||||
using util::unConst;
|
||||
using util::cStr;
|
||||
using util::_Fmt;
|
||||
|
|
@ -98,7 +124,7 @@ namespace diff{
|
|||
* @see DiffVirtualisedApplication_test demonstration of usage
|
||||
*/
|
||||
template<>
|
||||
class DiffApplicationStrategy<TreeMutator>
|
||||
class DiffApplicationStrategy<DiffMutable>
|
||||
: public TreeDiffInterpreter
|
||||
{
|
||||
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #992
|
||||
|
|
@ -432,7 +458,7 @@ namespace diff{
|
|||
|
||||
public:
|
||||
explicit
|
||||
DiffApplicationStrategy(TreeMutator& targetBinding)
|
||||
DiffApplicationStrategy(DiffMutable& targetBinding)
|
||||
{
|
||||
TODO("attach to the given Target");
|
||||
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #992
|
||||
|
|
|
|||
|
|
@ -101,10 +101,14 @@ namespace test{
|
|||
;
|
||||
}
|
||||
|
||||
TreeMutator
|
||||
exposeMutator()
|
||||
void
|
||||
buildMutator (TreeMutator::Handle buff)
|
||||
{
|
||||
UNIMPLEMENTED("find a way, how to build and expose a custom TreeMutator, without revealing details...");
|
||||
UNIMPLEMENTED("construct the concrete Binding, using the TreeMutator::Builder DSL");
|
||||
buff.create (
|
||||
TreeMutator::build()
|
||||
.attach (collection(nestedData_)
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -128,7 +132,7 @@ namespace test{
|
|||
* what these elements actually are and how they are to be handled.
|
||||
* - we recurse into mutating such an _"unspecified"_ child element.
|
||||
*
|
||||
* @todo this test defines a goal!! What has to be done, is to invent some test data structure and then run the exiting diffs against it. This requires the TreeMutator implementation to be finished!!!
|
||||
* @todo this test is WIP as of 6/2016 !! What has to be done, is to work out a way how to create a TreeMutator binding. And of course, we need the Implementation of DiffApplicator<DiffMutable>
|
||||
* @note this test uses the same verb sequence as is assumed for the
|
||||
* coverage of diff building blocks in TreeMutatorBinding_test
|
||||
*
|
||||
|
|
@ -204,8 +208,8 @@ namespace test{
|
|||
run (Arg)
|
||||
{
|
||||
Opaque subject;
|
||||
auto target = subject.exposeMutator(); /////////////////////TODO damn it! what type can we expose here? And, we need move initialisation!
|
||||
DiffApplicator<TreeMutator> application(target);
|
||||
DiffMutable& target = mutatorBinding (subject);
|
||||
DiffApplicator<DiffMutable> application(target);
|
||||
//
|
||||
// TODO verify results
|
||||
cout << "before..."<<endl << subject<<endl;
|
||||
|
|
|
|||
|
|
@ -8355,7 +8355,7 @@ attached to a clip, or the mixture of clips, effects and labels found within a [
|
|||
You should note that this entire design is recursive: only after understanding the part, where, for handling a sub-structure, a nested mutator is fabricated and placed into a given buffer, it becomes clear to what effect we're creating a customised mutator: we always need some (relative) parent scope, which happens to know more about the actual data to be treated with a TreeMutator. This scope assists with creating a suitable binding. Obviously, from within that binding, it is known what the sub-structures and children of that local data are all about and what semantics to give to the fundamental operations.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="TreeMutatorEvolution" creator="Ichthyostega" modifier="Ichthyostega" created="201603160255" modified="201605241839" tags="Model Concepts design draft" changecount="20">
|
||||
<div title="TreeMutatorEvolution" creator="Ichthyostega" modifier="Ichthyostega" created="201603160255" modified="201606132308" tags="Model Concepts design draft" changecount="21">
|
||||
<pre>The TreeMutator is an intermediary to translate a generic structure pattern into heterogeneous local invocation sequences.
|
||||
|
||||
!Motivation
|
||||
|
|
@ -8496,9 +8496,23 @@ Consequently, we're left with only a very limited subset of diff expression appl
|
|||
To create a ''binding'' for any object field, we need
|
||||
* a ''name'' for matching keys
|
||||
* either a ''setter'' (lambda) or a ''mutator builder'' (lambda)
|
||||
We have a distinct typing for each individual attribute, but this typing remains implicit: the lambda has to know what value to extract from the GenNode payload within the accepted diff message and how to apply this value. Especially for ''time entities'', which are modelled as immutable values, the lambda might want to build a [[time mutator|TimeMutation]]. And especially in the UI, timing specifications are expeted to be translated into a //presentation grid.//
|
||||
We have a distinct typing for each individual attribute, but this typing remains implicit: the lambda has to know what value to extract from the GenNode payload within the accepted diff message and how to apply this value. Especially for ''time entities'', which are modelled as immutable values, the lambda might want to build a [[time mutator|TimeMutation]]. And especially in the UI, timing specifications are expected to be translated into a //presentation grid.//
|
||||
|
||||
|
||||
!Implementation
|
||||
__June 2016__: after defining and implementing several concrete bindings successfully, the TreeMutator interface can be considered a given now. It seems conceivable even to try re-implementing the (already existing, hard wired) binding for GenNode in terms of a TreeMutator with specially outfitted binding. Anyway, matters are investigated and clarified enough in order to build the actual diff application based on this new TreeMutator interface. Some tricky structural and technical problems remain to be solved for that
|
||||
|
||||
!!!size of the concrete TreeMutator
|
||||
Since our design avoids subclassing and does not demand the target data to comply to any interface, we get a //late binding// where the actual configuration and thus the behaviour of the concrete mutator is configured with lambdas at runtime, just before the diff is actually applied. This gets us into a situation somewhere between static and dynamic typing -- the functionality of the binding, as embodied into the lambdas, is of course known at compilation time, but we can't access this knowledge until right before invocation, when the actual instance is created at runtime. The problem with this is that we need to know the size of the mutator beforehand, since our diff language is defined in a way preventing recursive evaluation on the stack. We're bound to create the stack for dealing with nested scopes explicitly, as a data structure -- which means we need to know the maximum size of nested mutators to expect, or we're forced into implementing a flexible stack structure with explicitly pointer linked global allocations. There are several possibilities how to deal with that problem
|
||||
* the //simplest approach that could possibly work// is to define a global constant for a buffer size known to be sufficient for all relevant cases. An attempt to exceed this pre-set limit will terminate the program
|
||||
* a slight extension to this approach is to differentiate this constant based on the type of the top-level data structure to be exposed
|
||||
* we could catch exceptions caused by exceeding a heuristically chosen buffer limit and //learn// the actually required size for successive attempts. Depending on the actual implementation situation, this requires some way of aborting and re-starting a failed attempt of diff application, which is an complicated and expensive undertaking. This also prompts us to make those size information part of the application parametrisation, with the ability to adjust those values persistently as a result of this self-adapting mechanism.
|
||||
Right now it looks sensible to start with the simplistic approach, while keeping the more elaborate possibilities in mind. Which especially means to turn the size management into an opaque implementation detail not linked to the visible diff-interpreter interface.
|
||||
|
||||
!!!implementation structure and invocation
|
||||
To receive and apply a diff, client code has to build a {{{DiffApplicator<TreeMutator>}}} and somehow attach this to the target data structure. Then, after feeding the diff sequence, the target data structure will be transformed. This leads to kind of a chicken-and-egg problem, since only the target data structure has the ability to know how to fabricate a suitable concrete TreeMutator. Assuming the //size problem// (as detailed above) is already solved one way or the other, we're bound to use an interface where the target structure is prompted to build a suitable mutator into a provided buffer or storage frame. Typically, we'd either use metaprogramming or some ADL extension point to derive a suitable //mutator building closure// from the given target structure. In fact, the same situation repeats itself recursively when it comes to mutating nested scopes, but in that case, the necessary //mutator building closure// is already part of the mutator binding created for the respective parent scope, and thus can just be invoked right away.
|
||||
|
||||
The {{{DiffApplicator}}} itself can be made non-copyable; preferably it should be small and cheap to construct. At least we should strive at keeping the number of indirections and heap allocations low. Together with the requirement to separate from the actual TreeMutator implementation, which is built late, just before invocation, we arrive at a ~PImpl structure, with the TreeMutator as ~PImpl and a scope manager hidden within the implementation part; the latter will be responsible for creating a suitable stack, and to use the //mutator building closure// in order to incorporate the concrete TreeMutator into the stack frames.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="TypedID" modifier="Ichthyostega" created="201003200157" modified="201505310143" tags="Model Types Rules design draft" changecount="12">
|
||||
|
|
|
|||
|
|
@ -1802,10 +1802,10 @@
|
|||
<node CREATED="1456430363599" ID="ID_1608232847" MODIFIED="1456505525321" TEXT="erlaube typ-gefilterte Kinder"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1456506101544" HGAP="4" ID="ID_133511037" MODIFIED="1456533241759" TEXT="Implementierung" VSHIFT="16">
|
||||
<node CREATED="1456506101544" HGAP="4" ID="ID_133511037" MODIFIED="1465674319651" TEXT="Implementierung" VSHIFT="16">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1456506128581" HGAP="-2" ID="ID_322289358" MODIFIED="1465428684559" TEXT="Abwägungen" VSHIFT="549">
|
||||
<node CREATED="1456506135028" FOLDED="true" HGAP="29" ID="ID_470489868" MODIFIED="1465428690281" TEXT="Indirektionen" VSHIFT="-5">
|
||||
<node CREATED="1456506135028" FOLDED="true" HGAP="29" ID="ID_470489868" MODIFIED="1465674277614" TEXT="Indirektionen" VSHIFT="-5">
|
||||
<node CREATED="1456506145826" ID="ID_759825167" MODIFIED="1461888854079" TEXT="kosten">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
|
@ -1941,7 +1941,7 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1457038737878" FOLDED="true" HGAP="44" ID="ID_643190842" MODIFIED="1465428691753" TEXT="Abstraktions-Grad">
|
||||
<node CREATED="1457038737878" FOLDED="true" HGAP="44" ID="ID_643190842" MODIFIED="1465674282709" TEXT="Abstraktions-Grad">
|
||||
<node CREATED="1457119812475" ID="ID_1862440484" MODIFIED="1457119817575" TEXT="Elemente bleiben opaque"/>
|
||||
<node CREATED="1457119818091" ID="ID_1097779694" MODIFIED="1457119984643">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
|
|
@ -4341,7 +4341,7 @@
|
|||
<node CREATED="1465664762944" ID="ID_1254081914" MODIFIED="1465665479208" TEXT="DiffApplicator<TreeMutator>">
|
||||
<icon BUILTIN="help"/>
|
||||
</node>
|
||||
<node CREATED="1465664777398" ID="ID_872861883" MODIFIED="1465664864246" TEXT="Automatismen sind denkbar">
|
||||
<node CREATED="1465664777398" ID="ID_872861883" MODIFIED="1465864148635" TEXT="Automatismen sind denkbar">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
|
|
@ -4364,6 +4364,7 @@
|
|||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<arrowlink COLOR="#994062" DESTINATION="ID_1139754084" ENDARROW="Default" ENDINCLINATION="1028;0;" ID="Arrow_ID_10673972" STARTARROW="None" STARTINCLINATION="978;42;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1465665483456" ID="ID_1329468559" MODIFIED="1465665491378" TEXT="Problem: konkreter Mutator">
|
||||
|
|
@ -4380,10 +4381,27 @@
|
|||
<node CREATED="1465665884698" ID="ID_418230667" MODIFIED="1465665893757" TEXT="default-Buffergöße vorlegen"/>
|
||||
<node CREATED="1465665894273" ID="ID_970277186" MODIFIED="1465665901124" TEXT="Größe proben und anpassen"/>
|
||||
<node CREATED="1465665901640" ID="ID_650164559" MODIFIED="1465665920298" TEXT="Größe für "bekannte" Targets statisch hinterlegen"/>
|
||||
<node CREATED="1465852237233" HGAP="27" ID="ID_699424989" MODIFIED="1465852303982" TEXT="Beschluß" VSHIFT="12">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1465852248487" ID="ID_1402619250" MODIFIED="1465852255154" TEXT="zunächst die einfachste Lösung"/>
|
||||
<node CREATED="1465852255694" ID="ID_462293433" MODIFIED="1465852267784" TEXT="statisch festlegen"/>
|
||||
<node CREATED="1465852268252" ID="ID_329653886" MODIFIED="1465852274743" TEXT="ggfs. noch nach Zieltyp differenziert"/>
|
||||
<node CREATED="1465852275859" ID="ID_394082851" MODIFIED="1465852288510" TEXT="dynamisch / Lernen als Möglichkeit vorsehen"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1465665614990" ID="ID_1851089586" MODIFIED="1465665618569" TEXT="verwirrendes API">
|
||||
<node CREATED="1465665980686" ID="ID_1537039073" MODIFIED="1465665991232" TEXT="Anwendung sollte selbstevident sein"/>
|
||||
<node CREATED="1465666009690" ID="ID_1006664389" MODIFIED="1465666034048" TEXT="Typ-Signatur sollte den Weg weisen"/>
|
||||
<node CREATED="1465666009690" ID="ID_1006664389" MODIFIED="1465666034048" TEXT="Typ-Signatur sollte den Weg weisen">
|
||||
<node CREATED="1465674483754" ID="ID_155190959" MODIFIED="1465674558135" TEXT="sehe nur eine Lösung">
|
||||
<icon BUILTIN="forward"/>
|
||||
</node>
|
||||
<node CREATED="1465674488874" ID="ID_625451231" MODIFIED="1465674563848" TEXT="Mutator-Builder-Funktion">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1465674529460" ID="ID_845292312" MODIFIED="1465674571112" TEXT="pflanzt in ein gegebenes Buff-Handle">
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="12"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1465665993012" ID="ID_1531461875" MODIFIED="1465666003750" TEXT="keine komplexen "Riten""/>
|
||||
<node CREATED="1465666524573" HGAP="30" ID="ID_462712191" MODIFIED="1465666537889" TEXT="Schlußfolgerung" VSHIFT="18">
|
||||
<icon BUILTIN="yes"/>
|
||||
|
|
@ -4394,6 +4412,87 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1465855369239" ID="ID_1875145732" MODIFIED="1465860759641" TEXT="Architektur">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1465855402346" ID="ID_390477158" MODIFIED="1465855405925" TEXT="Grundgedanke">
|
||||
<node CREATED="1465855407129" ID="ID_1269101170" MODIFIED="1465855418148" TEXT="Trennung von DiffInterpreter und TreeMutator"/>
|
||||
<node CREATED="1465855418880" ID="ID_118862910" MODIFIED="1465855431490" TEXT="ersterer wird auf Basis von letzterem implementiert"/>
|
||||
<node CREATED="1465855507380" ID="ID_63018388" MODIFIED="1465855526320">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
TreeMutator-<i>Binding</i> muß opaque bleiben
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1465855561877" ID="ID_1466552960" MODIFIED="1465855592311">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Buffer-Größen-Management <i>vorsehen</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<node CREATED="1465855596992" ID="ID_1925577989" MODIFIED="1465855605363" TEXT="passiert im Scope des Ctors"/>
|
||||
<node CREATED="1465855605879" ID="ID_961922886" MODIFIED="1465855611850" TEXT="bzw. im Scope des MUT-Verbs"/>
|
||||
<node CREATED="1465855641898" ID="ID_1420998207" MODIFIED="1465855731999" TEXT="Heuristik + Versuch&Irrtum">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
das heißt
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
ein sinnvoller Startwert wird heuristisch vorgegeben
|
||||
</li>
|
||||
<li>
|
||||
wenn die Allokation scheitert, die Exception fangen und die tatsächlich benötigte Größe merken
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1465855653265" ID="ID_1093267368" MODIFIED="1465855739025" TEXT="konfigurieren und lernen"/>
|
||||
</node>
|
||||
<node CREATED="1465855576187" ID="ID_1820859855" MODIFIED="1465855585389" TEXT="zunächst jedoch primitiv implementieren"/>
|
||||
</node>
|
||||
<node CREATED="1465856069657" ID="ID_1074974681" MODIFIED="1465856071677" TEXT="Struktur">
|
||||
<node CREATED="1465856074888" ID="ID_63334235" MODIFIED="1465856081531" TEXT="TreeMutator == PImpl"/>
|
||||
<node CREATED="1465856092638" ID="ID_587610953" MODIFIED="1465856106200" TEXT="BufferManager : opaque aber inline"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1465864106739" ID="ID_1139754084" MODIFIED="1465864153301" TEXT="Zugang zum Mutator-Binding">
|
||||
<linktarget COLOR="#994062" DESTINATION="ID_1139754084" ENDARROW="Default" ENDINCLINATION="1028;0;" ID="Arrow_ID_10673972" SOURCE="ID_872861883" STARTARROW="None" STARTINCLINATION="978;42;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1465864167187" ID="ID_1126324374" MODIFIED="1465864171974" TEXT="Aufruf: freie Funktion"/>
|
||||
<node CREATED="1465864172514" ID="ID_523639016" MODIFIED="1465864180668" TEXT="delegiert auf Template"/>
|
||||
<node CREATED="1465864181193" ID="ID_214760095" MODIFIED="1465864192611" TEXT="explizite / regelbasierte Spezialisierung"/>
|
||||
<node CREATED="1465864193607" ID="ID_910823091" MODIFIED="1465864216053" TEXT="Problem: Storage für die Closure">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1465864217628" ID="ID_234805162" MODIFIED="1465864228510" TEXT="typischerweise sind alles transiente Objekte"/>
|
||||
<node CREATED="1465864229170" ID="ID_1100042937" MODIFIED="1465864240501" TEXT="also muß die Closure als Wert-Objekt rausgegeben werden"/>
|
||||
<node CREATED="1465864247152" ID="ID_1684145985" MODIFIED="1465864259507" TEXT="gesucht: elegantes API">
|
||||
<icon BUILTIN="pencil"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1465860736044" ID="ID_40337378" MODIFIED="1465860740383" TEXT="Implementierung"/>
|
||||
<node CREATED="1465860740971" ID="ID_1662787747" MODIFIED="1465860752949" TEXT="Unit-Test">
|
||||
<icon BUILTIN="pencil"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1465428871136" ID="ID_1015843161" MODIFIED="1465428881634" TEXT="integration mehrerer Bindungs-Layer"/>
|
||||
<node CREATED="1465428882150" ID="ID_1889489833" MODIFIED="1465428890897" TEXT="komplexer Integrationstest"/>
|
||||
|
|
@ -4429,6 +4528,12 @@
|
|||
</node>
|
||||
</node>
|
||||
<node CREATED="1458850212503" ID="ID_321552356" MODIFIED="1458850218977" TEXT="Signaturen für Lambdas dokumentieren"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1465860661877" ID="ID_942624903" MODIFIED="1465860714295" TEXT="Builder-API für Attribut-Binding dokumentieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1465860672852" ID="ID_432641404" MODIFIED="1465860718271" TEXT="Variante zum Attribut-Binding, wobei die Attribut-ID als GenNode::ID gegeben ist">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node CREATED="1460847222865" ID="ID_362820787" MODIFIED="1461888854414" TEXT="abstrakte operationale Semantik der Diff-Anwendung dokumentieren">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
|
|
|||
Loading…
Reference in a new issue