diff --git a/src/lib/diff/tree-mutator-attribute-binding.hpp b/src/lib/diff/tree-mutator-attribute-binding.hpp index 398aa5963..276910f25 100644 --- a/src/lib/diff/tree-mutator-attribute-binding.hpp +++ b/src/lib/diff/tree-mutator-attribute-binding.hpp @@ -51,7 +51,7 @@ ** On the other hand, this very notion of _ordering_ and _sequence_ is essential to the ** meaning of "diff", as far as collections of "children" are involved. This leaves us ** with the decision, either to increase complexity of the diff language's definition - ** and concept, absorb this discrepancy within the complexity of implementation. + ** and concept, or to accommodate this discrepancy within the binding implementation. ** Deliberately, the whole concept of a "diff language" builds onto the notion of ** _layered semantics,_ where the precise meaning of some terms remains a private ** extension within specific usage context. There is a lot of leeway within the @@ -84,6 +84,14 @@ ** constructing the concrete TreeMutator needs to have adequate understanding ** regarding mode of operation and "mechanics" of such a binding. ** + ** @remark for sake of completeness an alternative binding option should be mentioned: + ** Attributes could be represented as a map of `(key,value)` pairs and then bound + ** via the STL collection binding. This way, all the attributes of an "object" + ** would be treated as coherent unit, within a single "onion layer". However, + ** such a layout tends to run against the conventions and the protocol of the + ** diff language and should be confined to cover some corner cases (e.g. to + ** support an open ended collection of _custom properties_) + ** ** @note the header tree-mutator-attribute-binding.hpp was split off for sake of readability ** and is included automatically from bottom of tree-mutator.hpp ** @@ -116,7 +124,7 @@ namespace diff{ /** * Generic behaviour of any binding to object fields (attributes). * Since object fields as such are part of the class definition, a diff - * will never be able to add, insert, delted or re-order fields. Thus we + * will never be able to add, insert, delete or re-order fields. Thus we * do not need to keep track of an "old" and "new" order; rather there * is always one single fixed element present to work on. * @note consequently, several diff operations are either implemented NOP, diff --git a/src/lib/diff/tree-mutator-collection-binding.hpp b/src/lib/diff/tree-mutator-collection-binding.hpp index 06dc6fd37..4903c1387 100644 --- a/src/lib/diff/tree-mutator-collection-binding.hpp +++ b/src/lib/diff/tree-mutator-collection-binding.hpp @@ -75,8 +75,75 @@ namespace diff{ using lib::iter_stl::eachElm; + /* === Technicalities of container access === */ + template + using _AsVector = std::vector; + template + using _AsMap = std::map; + + template + using IF_is_vector = lib::meta::enable_if< std::is_base_of<_AsVector, C>>; + template + using IF_is_map = lib::meta::enable_if< std::is_base_of<_AsMap, C>>; + + + /** Helper for uniform treatment of various STL containers */ + template + struct ContainerTraits + { + static_assert (not sizeof(C), "unable to determine any supported container type for C"); + }; + + template + struct ContainerTraits > + { + using Vec = _AsVector; + using Elm = typename Vec::value_type; + using Itr = typename Vec::iterator; + static Itr + recentElmRawIter (Vec& vec) + { + return Itr{&vec.back()}; + } + + static void + append (Vec& vec, Elm&& elm) + { + vec.emplace_back (forward (elm)); + } + }; + + template + struct ContainerTraits > + { + using Map = _AsMap; + using Key = typename Map::key_type; + using Val = typename Map::mapped_type; + using Elm = std::pair; + + /** heuristic for `std::map`: lookup via reverse iterator. + * Since std::map iterates in key order, the most recently inserted + * element is likely also the largest element. If this guess fails, + * there will always be a second try by searching over all elements. + */ + static auto + recentElmRawIter (Map& map) + { + auto& recentPos = ++map.rend(); + return map.find (recentPos->first); + } + + static void + append (Map& map, Elm&& elm) + { + map.emplace (forward (elm)); + } + }; + + + /** * Attach to collection: Concrete binding setup. * This record holds all the actual binding and closures @@ -101,6 +168,7 @@ namespace diff{ { using Coll = typename Strip::TypeReferred; using Elm = typename Coll::value_type; + using Trait = ContainerTraits; using iterator = typename lib::iter_stl::_SeqT::Range; using const_iterator = typename lib::iter_stl::_SeqT::Range; @@ -150,7 +218,7 @@ namespace diff{ void inject (Elm&& elm) { - emplace (collection, forward(elm)); + Trait::append (collection, forward(elm)); } iterator @@ -161,11 +229,13 @@ namespace diff{ return pos; } + /** locate element for assignment or mutation, + * with special shortcut to the recently inserted element */ iterator locate (GenNode const& targetSpec) { if (not collection.empty() - and matches (targetSpec, recentElm(collection))) + and matches (targetSpec, recentElm())) return recentElmIter(); else return search (targetSpec, eachElm(collection)); @@ -182,65 +252,13 @@ namespace diff{ iterator recentElmIter() { - return iterator (recentElmRawIter(collection), collection.end()); + return iterator{Trait::recentElmRawIter (collection), std::end (collection)}; } - template - static auto - recentElmRawIter (C& coll) ///< fallback: use first element of container + Elm& + recentElm() { - return coll.begin(); - } - - template - using Map = std::map; - - template - static auto - recentElmRawIter (Map& map) ///< workaround for `std::Map`: lookup via reverse iterator - { - return map.find (recentElm(map).first); - } - - static auto - recentElmRawIter (std::vector& vec) - { - return typename std::vector::iterator (&vec.back()); - } - - - template - static Elm& - recentElm (C& coll) - { - return *coll.begin(); - } - - template - static E& - recentElm (Map& map) - { - return *++map.rend(); - } - - static Elm& - recentElm (std::vector& vec) - { - return vec.back(); - } - - - template - static void - emplace (C& coll, Elm&& elm) - { - coll.emplace (forward (elm)); - } - - static void - emplace (std::vector& coll, Elm&& elm) - { - coll.emplace_back (forward (elm)); + return *Trait::recentElmRawIter (collection); } }; diff --git a/tests/library/diff/diff-tree-application-simple-test.cpp b/tests/library/diff/diff-tree-application-simple-test.cpp index adf82b2a1..d7448c5b4 100644 --- a/tests/library/diff/diff-tree-application-simple-test.cpp +++ b/tests/library/diff/diff-tree-application-simple-test.cpp @@ -163,7 +163,7 @@ namespace test{ { buff.create ( TreeMutator::build() - .attach (collection (static_cast&> (*this)) + .attach (collection (*this) )); } diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 18aab0f8d..6b08d22e6 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -9690,7 +9690,7 @@ attached to a clip, or the mixture of clips, effects and labels found within a [ You might have noticed already that this entire design is recursive: there is some part, where -- for handling a sub-structure -- a nested mutator is fabricated and placed into a given buffer. And only after understanding that part, it becomes clear to what end we are 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. -
+
The TreeMutator is an intermediary to translate a generic structure pattern into heterogeneous local invocation sequences.
 This page details some of the reasoning and documents decisions taken while shaping the chosen design.
 
@@ -9845,7 +9845,10 @@ So we arrive a the following guidelines:
 
 !!!types, attributes and layering
 During the analysis it turned out that support for a mixed set of //typed child elements// is an important goal. However, we may impose the restriction that these typed sub collections will be kept segregated and not be mixed up within the child scope. Effectively, this was already the fundamental trait for the //symbolic object representation// chosen here. Thus, "attributes" become just one further kind of typed children; even "metadata" might be treated along these lines in future (currently, as of 2016 we have only one single piece of metadata, the type field in {{{diff::Record}}}, which is treated explicitly in the code).
-This observation leads directly to an implementation based on layered decorators. Each kind of target elements will be treated by another decorator exclusively, and control is passed through a chain of such decorators. This means, each decorator (or "onion-layer") gets into charge based on a //selector predicate,// which works on the given diff verb solely (no introspection and no "peeking" into the implementation data). We should note though, that this implies some fine points of the diff language semantics are subject to this architectural decision -- especially the precise behaviour of the {{{AFTER}}}-verb depends on the //concrete layer structure// used at the target of the diff. Yet this seems acceptable, since it is the very nature of diff application to be dependent on internals of the target location -- just by definition we assume this inner structure of the target to be semantically congruent with the diff's source structure.
+This observation leads directly to an implementation based on layered decorators. Each kind of target elements will be treated by another decorator exclusively, and control is passed through a chain of such decorators. Consequently, each decorator (or "onion-layer") gets into charge based on a //selector predicate,// which works on the given diff verb solely (no introspection and no "peeking" into the implementation data). We should note though, that this implies some fine points of the diff language semantics are subject to this architectural decision -- especially the precise behaviour of the {{{AFTER}}}-verb depends on the //concrete layer structure// used at the target of the diff. Yet this seems acceptable, since it is the very nature of diff application to be dependent on internals of the target location -- just by definition we assume this inner structure of the target to be semantically congruent with the diff's source structure.
+
+!!!an alternative approach to »attributes«
+In the end, the implementation resulting from this layered decorator solution leads to another, alternative solution to deal with //object properties:// using an ''Attribute Map''. Obviously, this solution is in direct contrast to the model of an object field as defined through the //object's class.// However, sometimes, some entities in practice will support an //open ended collection of optional custom properties// -- and this is where the attribute map model shines. And it should be noticed that the implementation of the attribute map binding comes basically for free, once we have a standard binding in place to handle STL collections. There is only one technical discrepancy to bridge: a mapping container might be ordered (and in fact {{{stl::map}}} is, implemented as red-black tree); an intrinsic ordering of the container's contents is in contradiction to the basic concept of the diff framework, which assumes there is an explicit order, which can be changed by fetching and inserting some elements. And thus, this alternative representation of »attributes« should not be pushed too far.
 
 
 !Implementation
diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm
index c380c4206..061031a7f 100644
--- a/wiki/thinkPad.ichthyo.mm
+++ b/wiki/thinkPad.ichthyo.mm
@@ -117,7 +117,7 @@
   
 
 
-
+
 
   
     
@@ -135,13 +135,14 @@
       
     
   
-
+
+
 
 
 
 
 
-
+
 
   
     
@@ -160,10 +161,11 @@
       Ganz anders Model::Tangible: dieses registriert sich bei der Konstruktion
     

-
+ +
- + @@ -176,7 +178,8 @@ aber so herum macht es mehr Sinn

-
+ +
@@ -200,7 +203,7 @@ - + @@ -229,7 +232,8 @@ BusTerm, das damit Nachrichten an den Nexus schicken kann.

-
+ +
@@ -256,7 +260,7 @@ - + @@ -269,9 +273,10 @@ Wartet nur noch auf proof-of-concept (DemoGuiRoundtrip)

-
+ + - + @@ -284,7 +289,8 @@ aber nur via einfacher "uplink"-Verbindung

-
+ +
@@ -340,7 +346,7 @@ - + @@ -350,7 +356,8 @@ ...es könnte auch den Feedback des Users meinen

-
+ +
@@ -368,7 +375,7 @@ - + @@ -387,7 +394,8 @@ Term-Signal nicht ausgesendet würde.

-
+ +
@@ -460,7 +468,7 @@ - + @@ -479,9 +487,10 @@ Anmerkung: ein "frestehendes" BusTerm ist valide und zugelassen, es hat halt nur eine uplink-Connection.

-
+ +
- + @@ -494,7 +503,8 @@ es muß dazu auch jede Menge Methoden implementieren.

-
+ +
@@ -604,7 +614,7 @@ - + @@ -623,7 +633,8 @@ Ein zu früher bzw. zu später Aufruf "fällt einfach hinten runter"

-
+ +
@@ -655,7 +666,7 @@
- + @@ -692,7 +703,8 @@ dann kann der Shutdown-Prozeß den Start des GUI überholen.

-
+ +
@@ -717,7 +729,7 @@
- + @@ -727,7 +739,8 @@ wirkt alles mehr oder weniger beliebig...

-
+ +
@@ -750,7 +763,7 @@ - + @@ -763,9 +776,10 @@ Speicherzugriffsfehler

-
+ +
- + @@ -783,7 +797,8 @@ - + + @@ -838,7 +853,7 @@ - + @@ -866,7 +881,8 @@ terminiert und dann tatsächlich den Fuktor aufrufen möchte

-
+ +
@@ -922,7 +938,7 @@ - + @@ -944,7 +960,8 @@ und ihre "Methoden" sind Commands auf der Session!

-
+ +
@@ -1093,7 +1110,7 @@ - + @@ -1111,7 +1128,8 @@ - + + @@ -1319,7 +1337,7 @@ - + @@ -1332,7 +1350,8 @@ Das wird eine ganze Me

-
+ + @@ -1423,7 +1442,7 @@ - + @@ -1439,10 +1458,11 @@ aber noch irgend ein Hund begraben liegt

-
+ +
- + @@ -1455,11 +1475,12 @@ Im Moment loggen wir nur ins textuelle Konsole-Log (NoBug)

-
+ +
- + @@ -1480,7 +1501,8 @@ mehr erscheint mir nicht sinnvoll; behandeln kann man solche Fehler ohnehin nicht.

-
+ +
@@ -1503,7 +1525,7 @@
- + @@ -1519,7 +1541,8 @@ obwohl jener doch genau der Anlaß war, diesen neuen Mechanismus zu bauen.

-
+ +
@@ -3925,7 +3948,7 @@
- + @@ -3938,7 +3961,8 @@ indem wir ein GTK-Signal erzeugen, das das Hauptfenster schließt

-
+ + @@ -3995,7 +4019,7 @@ - + @@ -4014,7 +4038,8 @@ eine einzige Funktion konkret durchdenkt: es läuft auf Spaghetti-Code hinaus

-
+ +
@@ -4037,7 +4062,7 @@ - + @@ -4047,7 +4072,8 @@ ...indem der NotificatonService nun vom UI-Manager gemanaged wird :)

-
+ +
@@ -4090,7 +4116,7 @@ - + @@ -4139,7 +4165,8 @@ }

-
+ +
@@ -4308,7 +4335,7 @@ - + @@ -4340,9 +4367,10 @@ Daher macht es Sinn, den Interface-Lebenszyklus ganz starr an den Disspatcher zu binden

-
+ +
- + @@ -4361,9 +4389,10 @@ was zwar jederzeit (via statisches/internes Session-API) verifizierbar ist, jedoch nicht offensichtlich

-
+ +
- + @@ -4385,7 +4414,8 @@ jederzeit wegbrechen kann, was dann heißt, daß irgend ein Aufruf eine Exception wirft

-
+ +
@@ -4413,7 +4443,7 @@ - + @@ -4423,7 +4453,8 @@ meint: zwei gekoppelte Statusvariable

-
+ +
@@ -4452,7 +4483,7 @@ - + @@ -4462,7 +4493,8 @@ meint: zwei gekoppelte Statusvariable

-
+ +
@@ -4513,7 +4545,7 @@ - + @@ -4529,7 +4561,8 @@ Aber ich akzeptiere es und verwende es jetzt als Treiber

-
+ + @@ -4588,7 +4621,7 @@ - + @@ -4598,9 +4631,10 @@ das Lock sorgt hier für konsistenten Zustand und Sichtbarkeit (memory barrier)

-
+ +
- + @@ -4610,7 +4644,8 @@ Lock ist hier das Dispatcher-Lock

-
+ +
@@ -4656,7 +4691,7 @@ - + @@ -4666,14 +4701,15 @@ ...wenn jemand zugreift

-
+ +
- + @@ -4691,7 +4727,8 @@ - + + @@ -4736,7 +4773,7 @@ - + @@ -4764,7 +4801,8 @@ Ich halte diese Fälle aber für in der Praxis nicht relevant,  und verzichte daher auf eine Spezialbehandlung

-
+ +
@@ -4865,7 +4903,7 @@ - + @@ -4889,7 +4927,8 @@ - + + @@ -4996,7 +5035,7 @@ - + @@ -5009,7 +5048,8 @@ die mehrfachen Indirektionen und das Ein-/Auspacken der Argumente

-
+ +
@@ -5050,7 +5090,7 @@ - + @@ -5066,7 +5106,8 @@ und die Argumente von links her zu schließen (currying)

-
+ +
@@ -5091,7 +5132,7 @@ - + @@ -5107,7 +5148,8 @@ wenn in der UI ein InvocationTrail angelegt wird.

-
+ +
@@ -5229,7 +5271,7 @@ - + @@ -5260,10 +5302,11 @@ and shift the allocation logic to the aforementioned higher level.

-
+ +
- + @@ -5273,7 +5316,8 @@ ...der aber irgendwann (demnächst in diesem Theater) umgebaut/zurückgebaut werden soll

-
+ +
@@ -5438,7 +5482,7 @@ - + @@ -5468,13 +5512,14 @@ - + + - + @@ -5501,7 +5546,8 @@ - + + @@ -5516,7 +5562,7 @@ - + @@ -5526,7 +5572,8 @@ vorbereitete Grundstrukturen für immer wiederkehrende Setups

-
+ + @@ -5545,7 +5592,7 @@ - + @@ -5570,7 +5617,8 @@ Und der Rest sollte so vertraut aussehen, daß es selbsterklärend wird.

-
+ +
@@ -5662,7 +5710,7 @@ - + @@ -5672,7 +5720,8 @@ ...welche ad hoc mit beiläufig geschriebenem Debug/Test-Code belegt werden

-
+ +
@@ -5780,7 +5829,7 @@ - + @@ -5793,7 +5842,8 @@ Im Zweifelsfall den GTK+ Inspector verwenden!

-
+ +
@@ -5812,7 +5862,7 @@
- + @@ -5822,7 +5872,8 @@ CSS genügt

-
+ +
@@ -5835,7 +5886,7 @@ - + @@ -5870,7 +5921,8 @@ }

-
+ +
@@ -5944,7 +5996,7 @@
- + @@ -5957,10 +6009,11 @@ daß die alte, obsolete Timeline zurückgebaut ist

-
+ +
- + @@ -5976,7 +6029,8 @@ bevor die Notification-Facade geöffnet werden konnte

-
+ +
@@ -6028,7 +6082,7 @@ - + @@ -6059,7 +6113,8 @@ Allerdings habe ich an der Stelle immer noch GTK-Assertions

-
+ +
@@ -6107,7 +6162,7 @@ - + @@ -6135,7 +6190,8 @@ ist, daß Gio::Application sofort auch gleich eine dBus-Verbindung hochfährt.

-
+ +
@@ -6283,7 +6339,7 @@ - + @@ -6308,7 +6364,8 @@ diesen "aktuellen Kontext" irgendwo aufzufischen

-
+ + @@ -6370,7 +6427,7 @@ - + @@ -6383,7 +6440,8 @@ und verwendet, und das ist auch gut so

-
+ +
@@ -6479,7 +6537,7 @@ - + @@ -6492,7 +6550,8 @@ InvocationTrail ist tot

-
+ +
@@ -6529,7 +6588,7 @@ - + @@ -6542,7 +6601,8 @@ und den Teufelskreis zu durchbrechen!

-
+ +
@@ -6581,7 +6641,7 @@ - + @@ -6594,9 +6654,10 @@ (Beispiel "in-point fehlt")

-
+ +
- + @@ -6612,7 +6673,8 @@ aber von einem externen State-Change getriggert wird

-
+ +
@@ -6628,7 +6690,7 @@
- + @@ -6650,7 +6712,8 @@ und das wäre unsinnig.

-
+ +
@@ -6662,7 +6725,7 @@
- + @@ -6675,7 +6738,8 @@ da es nur darum geht, via globalCtx auf den passenden Controller zuzugreifen

-
+ +
@@ -6936,7 +7000,7 @@
- + @@ -6946,9 +7010,10 @@ ...and this anchorage can be covered and backed by the currently existing UI configuration

-
+ +
- + @@ -6958,9 +7023,10 @@ ...by interpolation of some wildcards

-
+ +
- + @@ -6970,7 +7036,8 @@ ...need to be extended to allow anchoring

-
+ +
@@ -6998,7 +7065,7 @@ - + @@ -7008,7 +7075,8 @@ we may construct the covered part of a given spec, including automatic anchoring.

-
+ +
@@ -7017,7 +7085,7 @@ - + @@ -7030,14 +7098,15 @@ designated by the given coordinate spec

-
+ + - + @@ -7059,7 +7128,8 @@ und dann kann man es auch extern belassen.

-
+ +
@@ -7093,7 +7163,7 @@
- + @@ -7106,7 +7176,8 @@ sind denkbar und müssen in der Strategy konfigurierbar sein?

-
+ + @@ -7207,7 +7278,7 @@ - + @@ -7229,7 +7300,8 @@ jedoch genügend aufgeschlossen, um die konkrete Implementierung fortzusetzen

-
+ + @@ -7648,7 +7720,7 @@ - + @@ -7667,9 +7739,10 @@ Grund: wir wollen vermeiden, abschließende Wildcards bloß irgendwie zu binden

-
+ +
- + @@ -7682,9 +7755,10 @@ dann aber Wildcards enthält, die nicht nach den verschärften Bedingungen gecovert werden können.

-
+ +
- + @@ -7705,7 +7779,8 @@ - + + @@ -7786,7 +7861,7 @@ - + @@ -7805,11 +7880,12 @@ denn eine Verletzung kann weithin unbemerkt bleiben

-
+ +
- + @@ -7831,11 +7907,12 @@ daraus resultierenden Pfad zugreift

-
+ +
- + @@ -7851,11 +7928,12 @@ Hierbei ist aktive Lebensdauer wie bei einem Iterator zu verstehen.

-
+ +
- + @@ -7868,7 +7946,8 @@ wenn die Auswertung aufgrund einer gebrochenen Konvention entgleist

-
+ +
@@ -7877,7 +7956,7 @@ - + @@ -7893,7 +7972,8 @@ Es gilt die erste maximal abdeckende Lösung

-
+ +
@@ -7904,7 +7984,7 @@ - + @@ -7917,9 +7997,10 @@ Sofern der Pfad bereits explizit ist, genügt diese Info allein

-
+ +
- + @@ -7937,7 +8018,8 @@ - + +
@@ -12072,7 +12154,7 @@
- + @@ -12082,7 +12164,8 @@ YAGNI

-
+ + @@ -12172,7 +12255,7 @@ - + @@ -12185,7 +12268,8 @@ oder verfangen wir uns da sofort zu sehr in der Implementierungs-Technik?

-
+ + @@ -12351,7 +12435,7 @@ - + @@ -12367,7 +12451,8 @@ Also sollte das auf dem API der default sein

-
+ +
@@ -12410,7 +12495,7 @@
- + @@ -12420,7 +12505,8 @@ ...das heißt: keine Wildcards, keine pseudo-Specs (currentWindow)

-
+ +
@@ -12428,7 +12514,7 @@ - + @@ -12438,7 +12524,8 @@ Zweck ist vor allem, meta-Specs wie firstWindow, currentWindow aufzulösen

-
+ +
@@ -12453,7 +12540,7 @@ - + @@ -12466,7 +12553,8 @@ als Repräsentation des real-existierenden UI

-
+ +
@@ -12524,7 +12612,7 @@ - + @@ -12540,7 +12628,8 @@ an einer Stelle über eine allgemeine Abstraktion

-
+ +
@@ -12585,7 +12674,7 @@
- + @@ -12595,9 +12684,10 @@ ...als Namespace-globale Variable mit externer Linkage

-
+ +
- + @@ -12621,7 +12711,8 @@ Grundsätzlich gilt hier die Einschätzung: Klarheit der Schnittstelle hat Vorrang

-
+ +
@@ -12708,7 +12799,7 @@ - + @@ -12721,7 +12812,8 @@ zweite hart-gecodete Fallback-Konfig

-
+ +
@@ -13180,7 +13272,7 @@
- + @@ -13196,7 +13288,8 @@ gegen den Kontext, mit dem sie matchen soll

-
+ + @@ -14582,7 +14675,7 @@ - + @@ -14592,7 +14685,8 @@ nämlich in lib::meta::func::PApply::bindBack

-
+ +
@@ -14610,7 +14704,7 @@ - + @@ -14641,7 +14735,8 @@ };

-
+ +
@@ -15062,7 +15157,7 @@ - + @@ -15081,7 +15176,8 @@ Daher denkt der Compiler, er kann das Ursprungsobjekt jezt wergwerfen.

-
+ +
@@ -15100,7 +15196,7 @@ - + @@ -15119,7 +15215,8 @@ bei der Navigation in einem realen GUI auftreten

-
+ +
@@ -15132,7 +15229,7 @@ - + @@ -15145,7 +15242,8 @@ daß ich mich wieder mal "akademisch" verspielt habe.... :-P

-
+ +
@@ -15164,7 +15262,7 @@ - + @@ -15177,7 +15275,8 @@ Schichten-Prinzip...

-
+ +
@@ -15613,7 +15712,7 @@ - + @@ -15641,7 +15740,8 @@ warum ViewLocator so nebulös bleibt: es gibt noch kein Lumiera GUI

-
+ + @@ -15699,7 +15799,7 @@ - + @@ -15709,7 +15809,8 @@ Policy: Unit-Tests dürfen keine GTK-Abhängigkeit haben

-
+ +
@@ -15733,7 +15834,7 @@ - + @@ -15754,7 +15855,8 @@ - + + @@ -15805,7 +15907,7 @@ - + @@ -15833,7 +15935,8 @@ bewirkt nur eine Entkoppelung vom Implementierungs-Kontext

-
+ +
@@ -15851,7 +15954,7 @@ - + @@ -15867,7 +15970,8 @@ sondern interpretieren jeweils nur eine einzige feste Konfiguration

-
+ +
@@ -15917,7 +16021,7 @@ - + @@ -15930,7 +16034,8 @@ um auszudrücken, daß gewissen Angaben ausgelassen wurden

-
+ +
@@ -16261,7 +16366,7 @@ - + @@ -16283,7 +16388,8 @@ dann bekommt man einen UICoord::Builder  und das ist noch keine Klausel!

-
+ +
@@ -16362,7 +16468,7 @@ - + @@ -16381,7 +16487,8 @@ aber es könnte durchaus sein, daß man auf sie generisch zugreifen möchte

-
+ +
@@ -16417,7 +16524,7 @@ - + @@ -16438,9 +16545,10 @@ In Fall-1 wird man eine bool-Abfrage machen wollen, und man kann auch mit einer false-Antwort umgehen. In Fall-2 dagegen bleibt nur noch der Tod. Und davon ist im Regelfall nicht auszugehen. Im Moment sehe ich Fall-2 als den standard-use-Case

-
+ +
- + @@ -16455,7 +16563,8 @@ - + + @@ -16489,7 +16598,7 @@ - + @@ -16508,7 +16617,8 @@ Die einzig interessante Information ist, ob es gelungen ist

-
+ +
@@ -16785,7 +16895,7 @@ - + @@ -16800,7 +16910,7 @@ - + @@ -16816,7 +16926,8 @@ und daher auf "inaktiv" geschaltet ist.

-
+ +
@@ -16848,7 +16959,7 @@ - + @@ -16867,7 +16978,8 @@ Habe verifiziert, daß diese Assertion tatsächlich greift

-
+ +
@@ -17068,7 +17180,7 @@ - + @@ -17081,7 +17193,8 @@ der es selbst vom Bus abkoppelt

-
+ +
@@ -17206,7 +17319,7 @@ - + @@ -17216,7 +17329,8 @@ ...denn das ist das vereinfachte Setup für "einfache" Applikationen

-
+ +
@@ -17380,7 +17494,7 @@ - + @@ -17399,7 +17513,8 @@ wenn es schon wirkliche und funktionierende Widgets im System gibt.

-
+ +
@@ -17414,7 +17529,7 @@
- + @@ -17424,7 +17539,8 @@ ...bisher erzeugt die lookup-Operation automatisch

-
+ +
@@ -17565,8 +17681,8 @@
- - + + @@ -17592,7 +17708,7 @@ - + @@ -17602,9 +17718,10 @@ das Diff wird auf den Platzhalter angewendet

-
+ +
- + @@ -17617,7 +17734,8 @@ dann muß dieses automatisch deregistriert werden

-
+ +
@@ -17790,7 +17908,7 @@ - + @@ -17800,9 +17918,10 @@ d.h. das Widget unternimmt selber nichts, und überläßt GTK die Größenbestimmung

-
+ +
- + @@ -17815,9 +17934,10 @@ Und sonst wird er Körper/Hintergrund ausgedehnt

-
+ +
- + @@ -17853,7 +17973,8 @@ Sehr wichtig für die Anzeige von langen Clips und Effekten.

-
+ + @@ -17982,7 +18103,7 @@ - + @@ -17995,7 +18116,8 @@ und welchen Teil des Verhaltens überlassen wir GTK

-
+ +
@@ -18028,7 +18150,7 @@ - + @@ -18054,9 +18176,10 @@ Aus Gründen der Konsistenz und Zukunftsfähigkeit

-
+ +
- + @@ -18087,7 +18210,8 @@ - + +
@@ -18102,7 +18226,7 @@
- + @@ -18118,7 +18242,8 @@ Details im  TiddlyWiki....

-
+ +
@@ -18172,7 +18297,7 @@ - + @@ -18182,7 +18307,8 @@ braucht feste Speicher-Addresse

-
+ +
@@ -18192,7 +18318,7 @@ - + @@ -18205,7 +18331,8 @@ und sei es auch bloß über ein Interface!

-
+ +
@@ -18221,7 +18348,7 @@ - + @@ -18255,7 +18382,8 @@ - + + @@ -18269,7 +18397,7 @@ - + @@ -18282,7 +18410,8 @@ Das bedeutet: viele Kind-Widgets werden auf diesem Canvas platziert und müssen daher mit ihm interagieren

-
+ +
@@ -18295,7 +18424,7 @@ - + @@ -18308,7 +18437,8 @@ Allerdings lebt das erzeugte Kind-ViewHooked danach eigenständig und es gibt keine weitere Beziehung

-
+ +
@@ -18317,7 +18447,7 @@ - + @@ -18327,10 +18457,11 @@ Erläuterung: man könnte auf die Idee kommen, die vier notwendigen Operationen auf dem Ziel durch Lambdas zu verkapseln. Wenn man dann aber nicht aufpaßt, resultiert das in einer Closure für jedes dieser vier Lamdas, und diese Closure hält zumindest einen Pointer auf das Zielobjekt. Der Vorteil eines solchen Ansatzes wäre natürlich, daß der konkrete Typ von Quelle und Ziel aus der Definition des ViewHook verschwindet (allerdings auch nur, wenn diese Lambdas in std::function-Objekte gewickelt sind)

-
+ +
- + @@ -18351,7 +18482,8 @@ - + + @@ -18361,7 +18493,7 @@ - + @@ -18371,7 +18503,8 @@ da der ViewHook schon zwei Pointer zu zwei Entitäten halten muß, kann man Redundanzen vermeiden, indem man ihn an einem dritten Ort anbringt. Nämlich an einem Ort, an dem ohnehin schon eine Dreiecksbeziehung mit diesen beiden Elementen besteht

-
+ +
@@ -18385,7 +18518,7 @@ - + @@ -18395,7 +18528,8 @@ Dies wäre dann das Rückgrat in der View-Behandlung in der Timeline

-
+ +
@@ -19188,7 +19322,7 @@ - + @@ -19198,12 +19332,13 @@ ...weil der Vater ja auch neue Kinder "hooken" kann

-
+ +
- + @@ -19213,7 +19348,8 @@ d.h. zugleich wird die alte Verbindung gelöst und die neue konstruiert

-
+ +
@@ -19242,7 +19378,7 @@
- + @@ -19252,7 +19388,8 @@ es gibt keinen prinzipiellen Grund, warum sie scheitern könnte

-
+ +
@@ -19283,7 +19420,7 @@ - + @@ -19293,7 +19430,8 @@ denn auch der Canvas ist ein Gtk::Container und hat eine Liste von Widgets

-
+ +
@@ -19323,7 +19461,7 @@ - + @@ -19333,9 +19471,10 @@ "the children of your friends ain't necessarily your friends"

-
+ +
- + @@ -19345,7 +19484,8 @@ ...sonst müßte man das Einfügen als eine weitere (protected)-Operation auf dem ViewHook ausdrücken und könnte dann die Erzeugung des ViewHooked fest in den ViewHook ABC implementieren....

-
+ +
@@ -19354,7 +19494,7 @@ - + @@ -19385,7 +19525,7 @@ - + @@ -19395,7 +19535,8 @@ weil nun ViewHooked schon als ctor-Parameter einen ViewHook bekommen muß...

-
+ + @@ -19429,7 +19570,7 @@ - + @@ -19439,7 +19580,8 @@ denn vernünftigerweise muß man davon ausgehen, daß der Canvas (oder wo auch immer das element platziert wird) sich einen Pointer speichert, und diesen später auch aktiv verwenden wird

-
+ +
@@ -19480,7 +19622,7 @@
- + @@ -19490,7 +19632,8 @@ again the problem with the reversed order due to forward_list

-
+ +
@@ -19530,7 +19673,7 @@
- + @@ -19543,7 +19686,8 @@ auf der rechten Seite, wo der Content angezeigt wird

-
+ + @@ -19557,7 +19701,7 @@ - + @@ -19567,7 +19711,8 @@ Das muß auch so sein, denn sonst wäre das systematische Modell und die Controller zu eng mit dem Display-Code verwoben. Der Nachteil ist aber, daß derart aufgedoppelte Struktur bei jeder Strukturänderung invalide wird

-
+ +
@@ -19636,7 +19781,7 @@ - + @@ -19646,7 +19791,8 @@ ...für die dritte Lösung, die Repräsentation bereits in der Session

-
+ +
@@ -19734,7 +19880,7 @@ - + @@ -19750,9 +19896,10 @@ Implementiert würde sie vom jeweiligen Widget

-
+ +
- + @@ -19780,9 +19927,10 @@ Der Dekorator würde also auf dem TreeMutator sitzen...

-
+ +
- + @@ -19801,9 +19949,10 @@ Daher gibt es die matchSrc-Operation. Effektiv wird die aber nur bei einem Delete aufgerufen...

-
+ +
- + @@ -19824,7 +19973,8 @@ - + + @@ -19917,7 +20067,7 @@ - + @@ -19927,7 +20077,8 @@ d.h. eine LUID

-
+ +
@@ -19961,7 +20112,7 @@ - + @@ -19971,7 +20122,8 @@ weil dies ggfs vom Theme her schon gestyled wird

-
+ +
@@ -19986,7 +20138,7 @@
- + @@ -20005,7 +20157,8 @@ in der C "class init function" passieren muß

-
+ +
@@ -20020,7 +20173,7 @@
- + @@ -20033,7 +20186,8 @@ Irgend eine BareEntryID genügt

-
+ +
@@ -20044,7 +20198,7 @@ - + @@ -20060,7 +20214,8 @@ Daher sollte eine inkompatible Strukturänderung überhaupt nicht auftreten können

-
+ +
@@ -20110,7 +20265,7 @@ - + @@ -20120,13 +20275,14 @@ ...abstraktes Interface

-
+ + - + @@ -20142,7 +20298,8 @@ um die Bindung herzustellen

-
+ +
@@ -20153,7 +20310,7 @@ - + @@ -20172,7 +20329,8 @@ und erwarten abweichend vom Standard ein vollständiges Skelett im INS-Verb

-
+ + @@ -20184,7 +20342,7 @@ - + @@ -20205,7 +20363,8 @@ - + + @@ -20223,7 +20382,7 @@ - + @@ -20251,7 +20410,8 @@ typischerweise wird es das in einem Populationsdiff sofort als Nächstes machen.

-
+ +
@@ -20274,7 +20434,7 @@ - + @@ -20294,7 +20454,8 @@ "was kann denn schon passieren??"

-
+ +
@@ -20325,7 +20486,7 @@ - + @@ -20346,9 +20507,10 @@ - + + - + @@ -20358,7 +20520,8 @@ einen Fall, der praktisch nie auftritt

-
+ +
@@ -20527,7 +20690,7 @@
- + @@ -20551,7 +20714,8 @@ - + + @@ -20638,7 +20802,7 @@ - + @@ -20651,7 +20815,8 @@ weil ein Layout-Manager immer nur im Bereich eines TimelineWidget relevant ist

-
+ +
@@ -20682,7 +20847,7 @@ - + @@ -20692,7 +20857,8 @@ ...und für Signale sind diese Probleme bereits gelöst

-
+ +
@@ -20704,7 +20870,7 @@ - + @@ -20719,7 +20885,8 @@ - + + @@ -20779,7 +20946,7 @@ - + @@ -20795,7 +20962,8 @@ aber die tatsächliche Neuberechnung erfolgt erst spät, und bei Bedarf

-
+ +
@@ -21091,7 +21259,7 @@ - + @@ -21109,10 +21277,11 @@ - + + - + @@ -21130,10 +21299,11 @@ - + + - + @@ -21154,10 +21324,11 @@ - + + - + @@ -21176,10 +21347,11 @@ STOP. Damit ist die virtuelle Methode nur verschoben

-
+ +
- + @@ -21192,9 +21364,10 @@ von dem nur erwartet wird, daß er eine "Verankerungs"-Funktion bietet

-
+ +
- + @@ -21207,7 +21380,8 @@ welchen er aufruft, um seine neu erstellten Widgets zu verankern

-
+ +
@@ -21253,7 +21427,7 @@ - + @@ -21271,7 +21445,8 @@ - + + @@ -21299,7 +21474,7 @@ - + @@ -21312,10 +21487,11 @@ und zwar der ctor-TrackPresenter

-
+ +
- + @@ -21328,13 +21504,14 @@ alle anderen verschachtelten ctors aber von den TrackPresentern

-
+ +
- + @@ -21344,9 +21521,10 @@ weil nur sie sowohl durch ihren Display-Frame die beiden Kind-Widgets kennen

-
+ + - + @@ -21356,9 +21534,10 @@ inwiefern gibt es Beschränkungen, wenn man ein Kind-Widget von einem Container entfernt?

-
+ + - + @@ -21368,7 +21547,8 @@ "This interface is used for all single item holding containers. Multi-item containers provide their own unique interface as their items are generally more complex. The methods of the derived classes should be prefered over these..."

-
+ + @@ -21489,7 +21669,7 @@
- + @@ -21499,7 +21679,8 @@ ...das ist zunächst ein Versuch, ein mühsam errungenes Design zu verifizieren...

-
+ + @@ -21570,7 +21751,7 @@ - + @@ -21580,7 +21761,8 @@ denn, wie sich herausgestellt hat, muß das Interface ViewHook hierarchisch heruntergebrochen werden

-
+ +
@@ -21713,7 +21895,7 @@
- + @@ -21726,7 +21908,8 @@ so z.B. sein Placement, welches teilweise als Properties des Track abgebildet wird.

-
+ +
@@ -21843,7 +22026,7 @@ - + @@ -21853,7 +22036,8 @@ weil der Ruler ja in die Präsentation mit einbezogen ist

-
+ +
@@ -21922,7 +22106,7 @@
- + @@ -21932,7 +22116,8 @@ ....ob es was sinnvolles in einem Overview-Ruler anzuzeigen gibt

-
+ +
@@ -21955,7 +22140,7 @@ - + @@ -21984,7 +22169,8 @@ zur Anwendung kommt

-
+ +
@@ -22014,7 +22200,7 @@ - + @@ -22033,7 +22219,8 @@ am Anfang des Track-Profils, welche immer sichtbar bleiben soll

-
+ +
@@ -22064,7 +22251,7 @@ - + @@ -22077,9 +22264,10 @@ stets besser ist, als repetitives aufdoppeln und variieren

-
+ +
- + @@ -22097,7 +22285,8 @@ - + + @@ -22130,7 +22319,7 @@ - + @@ -22155,7 +22344,8 @@ und daher nicht a priori die Liste aller einzubettenden Varianten kenne

-
+ +
@@ -22703,7 +22893,7 @@ - + @@ -22713,9 +22903,10 @@ sollten z.B. die Konstruktor-Funktionen nicht unmittelbar mit definiert werden?

-
+ +
- + @@ -22728,10 +22919,11 @@ Wie auch im konkreten Fall das TrackProfile, was dann ein vector<VerbPack> werden würde?

-
+ +
- + @@ -22750,7 +22942,8 @@ und es obliegt der nächst höheren Schicht, dies auch in sinnvollem Rahmen zu tun...

-
+ + @@ -22772,7 +22965,7 @@ - + @@ -22788,9 +22981,10 @@ innerhalb eines PolymorphicValue.

-
+ +
- + @@ -22806,7 +23000,8 @@ stets selbst erzeugen und daher auf das korrekte Literal Verlaß ist)

-
+ +
@@ -22823,7 +23018,7 @@ - + @@ -22839,7 +23034,8 @@ und soll von beiden sub-Canvas gleichermaßen jeweils passend interpretiert werden

-
+ +
@@ -22855,7 +23051,7 @@ - + @@ -22865,9 +23061,10 @@ ...daher die Factory

-
+ +
- + @@ -22882,7 +23079,8 @@ - + + @@ -22973,7 +23171,7 @@ - + @@ -22983,13 +23181,14 @@ weil man damit eine generische Klammer bauen kann

-
+ +
- + @@ -22999,7 +23198,8 @@ und bleibt anderweitig ungenutzt

-
+ +
@@ -23009,7 +23209,7 @@ - + @@ -23019,7 +23219,8 @@ ...ist klarer, und erlaubt nebenbei auch noch, zwei Methoden einzusparen

-
+ +
@@ -23155,7 +23356,7 @@ - + @@ -23213,10 +23414,11 @@   }

-
+ +
- + @@ -23232,7 +23434,8 @@ Macht trotzdem nix

-
+ +
@@ -23240,7 +23443,7 @@
- + @@ -23256,11 +23459,12 @@ Problem ist aber, daß diese Zuweisung später, nach einem set_size auf dem Canvas nicht revidiert wird.

-
+ + - + @@ -23270,11 +23474,12 @@ die Funktionen zum expliziten Setzen und re-Sizing sind deprecated.

-
+ +
- + @@ -23293,7 +23498,8 @@ ich sollte diese Logik besser selber explizit ausprogrammieren

-
+ +
@@ -23319,7 +23525,7 @@ - + @@ -23329,7 +23535,8 @@ ...im Session-Modell für eine Timeline jeweils ein Property hierfür geben...

-
+ +
@@ -23347,7 +23554,7 @@ - + @@ -23366,7 +23573,8 @@ Irgendjemand muß mal den Müll runtertragen

-
+ +
@@ -23503,7 +23711,7 @@ - + @@ -23516,7 +23724,8 @@ Kein Wunder daß die meisten UIs aus Sicht des Programmierers ein Albtraum sind

-
+ + @@ -23723,7 +23932,7 @@ - + @@ -23733,7 +23942,8 @@ ...in dem der Timeline body-canvas nämlich liegt

-
+ +
@@ -23805,7 +24015,7 @@ - + @@ -23815,7 +24025,8 @@ wir können nicht von 0 bis MAXINT zeichnen

-
+ +
@@ -23867,7 +24078,7 @@ - + @@ -23883,7 +24094,8 @@ Und letztere neigt stets zur "Verschlimmbesserung"

-
+ +
@@ -23901,7 +24113,7 @@ - + @@ -23914,9 +24126,10 @@ Wohl aber lassen sich lokale Nachbarschafts-Beziehungen (höhe / tiefer) durch Schattierung hervorheben

-
+ +
- + @@ -23929,7 +24142,8 @@ Die Inhalts-Flächen selber sind zu groß und zu strukturiert, um sie per Schattierung zu verdeutlichen

-
+ +
@@ -23961,7 +24175,7 @@ - + @@ -23971,7 +24185,8 @@ ...zum Beispiel um einen "Wall" auch expressiv zu schattieren

-
+ +
@@ -24485,7 +24700,7 @@ - + @@ -24501,7 +24716,8 @@ wenn er mit der HeaderPane den benötigten Platz aushandelt

-
+ + @@ -24542,7 +24758,7 @@ - + @@ -24555,7 +24771,8 @@ Damit werden effektiv die "schließenden Klammern" in eine einzige zusammengefaßt

-
+ +
@@ -24600,7 +24817,7 @@ - + @@ -24610,7 +24827,8 @@ nicht nur die Ruler, auch das Prelude selber ist ein solches gePinntes Element (selbst wenn es leer ist)

-
+ +
@@ -24647,7 +24865,7 @@ - + @@ -24671,9 +24889,10 @@ - + + - + @@ -24693,7 +24912,8 @@ denn was passiert, wenn sich durch das Setzen einer neuen Größe der sichtbare Bereich ändert? Löst das dann nicht erneut einen draw()-Aufruf aus??

-
+ +
@@ -24702,7 +24922,7 @@ - + @@ -24712,7 +24932,8 @@ ist ineffizient, aber der Code ist so klarer

-
+ +
@@ -24756,7 +24977,7 @@ - + @@ -24776,7 +24997,8 @@ Core-Entwickler von GTK

-
+ + @@ -24957,7 +25179,7 @@ - + @@ -24975,13 +25197,14 @@ - + + - + @@ -24991,7 +25214,8 @@ der GTK-Zeichencode achtet sogar explizit darauf, einen CSS-Effekt mit dem korrekten Mischmodus über den bereits auf den CairoCanvas gezeichneten Content zu legen

-
+ +
@@ -25012,7 +25236,7 @@ - + @@ -25022,7 +25246,8 @@ weil über alles andere darübergezeichnet wird

-
+ +
@@ -25037,7 +25262,7 @@
- + @@ -25047,7 +25272,8 @@ den Zeichenvorgang für ein normales Frame-Widget analysieren

-
+ + @@ -25257,7 +25483,7 @@ - + @@ -25267,7 +25493,8 @@ weil er dann mehr oder weniger hartverdrahtet ist

-
+ +
@@ -25617,7 +25844,7 @@ - + @@ -25630,7 +25857,8 @@ Daher verzichte ich global (für die Slopes) darauf, wende sie aber lokal  an

-
+ +
@@ -25671,7 +25899,7 @@ - + @@ -25681,7 +25909,8 @@ ...wo parktischerweise der Style-Advice in einer lokalen statischen Variablen liegt

-
+ +
@@ -25728,7 +25957,7 @@
- + @@ -25741,7 +25970,8 @@ Und nicht die sichtbare Größe

-
+ +
@@ -25769,7 +25999,7 @@ - + @@ -25787,7 +26017,8 @@ - + + @@ -25838,7 +26069,7 @@ - + @@ -25856,7 +26087,8 @@ - + + @@ -25928,7 +26160,7 @@ - + @@ -25938,7 +26170,8 @@ weil dann der Platz für den "pinned" Ruler redundant im Body-Canvas vorhanden ist!

-
+ +
@@ -25978,7 +26211,7 @@ - + @@ -25988,7 +26221,8 @@ weil die Canvas-Controls tief eingewickelt in der Struktur liegen

-
+ + @@ -26047,7 +26281,7 @@ - + @@ -26063,9 +26297,10 @@ die sich nur beim Scrollen bemerkbar macht

-
+ +
- + @@ -26075,7 +26310,8 @@ man soll ohnehin keinen so großen box-shadow verwenden

-
+ +
@@ -26175,7 +26411,7 @@ - + @@ -26185,7 +26421,8 @@ ...sie verwenden dann ein LabelWidget zur Darstellung

-
+ +
@@ -26231,7 +26468,7 @@ - + @@ -26241,7 +26478,8 @@ ERR: nexus.hpp:189: worker_3: ~Nexus: Some UI components are still connected to the backbone.

-
+ +
@@ -26316,7 +26554,7 @@ - + @@ -26332,7 +26570,8 @@ Verwende das als Leitgedanke, um das Layout zu entwickeln

-
+ + @@ -26487,7 +26726,7 @@ - + @@ -26497,7 +26736,8 @@ ...um mal was im UI anzeigen zu können

-
+ +
@@ -26593,7 +26833,7 @@ - + @@ -26606,7 +26846,8 @@ mehr als ein top-level Fenster offen

-
+ +
@@ -26615,7 +26856,7 @@ - + @@ -26628,7 +26869,8 @@ which reference actions from one or more action groups.

-
+ +
@@ -26637,7 +26879,7 @@ - + @@ -26666,7 +26908,8 @@ AUA!

-
+ +
@@ -26688,7 +26931,7 @@ - + @@ -26710,9 +26953,10 @@ auch nicht im Application-Shutdown!

-
+ +
- + @@ -26725,13 +26969,14 @@ dock_.add_item(timelinePanel->getDockItem(),Gdl::DOCK_BOTTOM);

-
+ +
- + @@ -26741,7 +26986,8 @@ Helper to build the menu and for registering and handling of user action events

-
+ +
@@ -26754,7 +27000,7 @@
- + @@ -26767,7 +27013,8 @@ aber es kann davon mehrere geben

-
+ +
@@ -27076,7 +27323,7 @@
- + @@ -27089,7 +27336,8 @@ die erlauben, eine Init-Aktion in die Loop zu schedulen

-
+ + @@ -27097,7 +27345,7 @@ - + @@ -27120,7 +27368,8 @@ sondern Sachen wie verallgemeinerte "Files", D-Bus-Connection etc etc

-
+ +
@@ -27134,7 +27383,7 @@ - + @@ -27149,7 +27398,8 @@ - + + @@ -27164,7 +27414,7 @@ - + @@ -27180,7 +27430,8 @@   //registered. (At least if window is an ApplicationWindow.)

-
+ + @@ -27192,7 +27443,7 @@
- + @@ -27205,7 +27456,8 @@ when an activation occurs. See g_application_activate().

-
+ + @@ -27226,7 +27478,7 @@ - + @@ -27247,7 +27499,8 @@ - + +
@@ -27315,7 +27568,7 @@ - + @@ -27325,7 +27578,8 @@ ...für Signale, die nicht automatisch detached werden können

-
+ +
@@ -27336,7 +27590,7 @@ - + @@ -27346,7 +27600,8 @@ @deprecated: 3.4: Key snooping should not be done. Events should  be handled by widgets

-
+ +
@@ -27357,7 +27612,7 @@ - + @@ -27382,7 +27637,8 @@ - + + @@ -27417,7 +27673,7 @@
- + @@ -27444,7 +27700,8 @@ - + + @@ -27536,7 +27793,7 @@ - + @@ -27549,11 +27806,12 @@ schon vor der Loop verfügbar zu sein (?)

-
+ +
- + @@ -27563,7 +27821,8 @@ nur bei laufender Event-Loop

-
+ +
@@ -27598,7 +27857,7 @@ - + @@ -27617,7 +27876,8 @@ Fenster gibt es gar keine Benutzer-Events.

-
+ +
@@ -27683,7 +27943,7 @@ - + @@ -27705,7 +27965,8 @@ und daher der Diff direkt und kompakt in einem Durchgang emittiert werden kann

-
+ +
@@ -27742,7 +28003,7 @@ - + @@ -27760,10 +28021,11 @@ - + + - + @@ -27778,7 +28040,8 @@ - + + @@ -27792,7 +28055,7 @@ - + @@ -27817,7 +28080,8 @@ - + + @@ -27959,7 +28223,7 @@ - + @@ -27972,7 +28236,8 @@ where 1 tick unit depends on the current zoom level

-
+ +
@@ -27980,7 +28245,7 @@
- + @@ -27995,12 +28260,13 @@ - + + - + @@ -28022,7 +28288,8 @@ Theoretisch könnte eine Skala auf einer Seite oder auf beiden Seiten limitiert sein....?

-
+ + @@ -28090,7 +28357,7 @@ - + @@ -28109,7 +28376,8 @@ analog zu gui::model::Tangible

-
+ +
@@ -28168,7 +28436,7 @@ - + @@ -28178,7 +28446,8 @@ weil wir einen Mechanismus haben, die <cnt>-Dekoration pro Typ global hochzuzählen (treadsafe)

-
+ +
@@ -28205,7 +28474,7 @@ - + @@ -28218,13 +28487,14 @@ von dem Container (GenNode) wissen, der es zwei Ebenen höher enthält und umschließt

-
+ +
- + @@ -28240,10 +28510,11 @@ Der Hash kann genausogut eine Zufallszahl sein

-
+ + - + @@ -28259,7 +28530,8 @@ sich über dieses Problem Gedanken zu machen

-
+ +
@@ -28292,7 +28564,7 @@ - + @@ -28308,9 +28580,10 @@ für global eindeutige IDs an den relevanten Stellen zu sorgen

-
+ + - + @@ -28320,7 +28593,8 @@ ...dem man eine EntryID geben kann

-
+ +
@@ -28524,7 +28798,7 @@ - + @@ -28543,7 +28817,8 @@ erfordert bereits Kenntnis der Innereien

-
+ +
@@ -28597,7 +28872,7 @@ - + @@ -28607,9 +28882,10 @@ heißt: Element registriert sich am UI-Bus

-
+ +
- + @@ -28619,11 +28895,12 @@ heißt: Element deregistriert sich am UI-Bus

-
+ +
- + @@ -28633,7 +28910,8 @@ ...ist immer ein tangible

-
+ +
@@ -28683,7 +28961,7 @@ - + @@ -28693,10 +28971,11 @@ dafür genügt der normale Reset

-
+ +
- + @@ -28706,9 +28985,10 @@ mark "clearMsg"

-
+ +
- + @@ -28718,9 +28998,10 @@ mark "clearErr"

-
+ +
- + @@ -28730,7 +29011,8 @@ mark "reset"

-
+ +
@@ -28756,7 +29038,7 @@
- + @@ -28779,9 +29061,10 @@ was haben alle UI-Elemente wirklich gemeinsam?

-
+ + - + @@ -28797,7 +29080,8 @@ oder handelt es sich nur um ein Implementierungsdetail der UI-Bus-Anbindung?

-
+ + @@ -28841,7 +29125,7 @@ - + @@ -28857,7 +29141,8 @@ Für die UI-Programmierung muß man Spaghetticode akzeptieren.

-
+ +
@@ -28887,7 +29172,7 @@ - + @@ -28900,10 +29185,11 @@ Dann mußte das allerdigns jeweils für alle Elemente sinnvoll sein

-
+ +
- + @@ -28913,7 +29199,8 @@ und der muß vom konkreten Widget implementiert werden

-
+ +
@@ -28984,7 +29271,7 @@ - + @@ -29022,7 +29309,8 @@ wenn es nicht sichtbar ist. Denn Sichtbarkeit gehört zur UI-Mechanik und geht den Client nix an

-
+ +
@@ -29037,7 +29325,7 @@ - + @@ -29059,7 +29347,8 @@ denn dann gäbe es eine Implementierung "von der Stange"

-
+ +
@@ -29230,7 +29519,7 @@ - + @@ -29265,12 +29554,13 @@ und eine state mark "reset" zurückschicken...

-
+ +
- - + + @@ -29289,7 +29579,7 @@ - + @@ -29428,7 +29718,7 @@ - + @@ -29702,7 +29992,7 @@ - + @@ -30117,7 +30407,7 @@ - + @@ -30661,7 +30951,7 @@ - + @@ -30680,7 +30970,7 @@ - + @@ -30693,3642 +30983,30 @@ durch den das Problem mit der "absrakten, opaquen" Position entschärft wird

-
+ +
- - - - - - - - - - -
    -
  • - Diff-Anwendung wird massiv und in der Breite stattfinden -
  • -
  • - sie wird als Reaktion auf UI-Events auftreten -
  • -
  • - sie dient dazu, andere UI-Operationen einzusparen -
  • -
  • - also muß speziell das Traversieren bis an den Anwendungsort bedacht werden -
  • -
- -
-
- - - - - - -

- ...d.h. die bis jetzt geschriebene TreeApplikator-Implementierung -

-

- ist erstaunlich leichtgewichtig. Zu den zwei Indirektionien der Sprache -

-

- kommt nur entweder ein weiterer aus der GenNode bzw stattedessen ein dynamic cast hinzu. -

-

- Alles andere steckt in dem expliziten Mutator-Typ -

-

-  -- das gibt einen wichtigen Hinweis -- -

- -
-
- - - - - - -

- ...da wir eine verb-basierte Sprache implementieren, -

-

- also einen double-dispatch haben -

- -
-
- - - - - - - - - - - - -

- weil wir den Anwendungs-Kontext noch überhaupt nicht kennen. -

-

- Man könnte also später, wenn das ganze System "steht", -

-

- das Diff-System noch einmal reimplementieren, dann mit einem vorgegebenen Diff-Typ -

- -
-
-
- +

- Beschluß: akzeptiert + Implementierung: Diff-Bindung -> Diff-System

-
- -
-
- - - - - - - - -

- im Sinn von "polymorpic value" ist das Backend virtuell -

- -
-
- - - - - - - - - -

- ....wenngleich auch dieser aus einem Template generiert wird -

-

- (will sagen, es ist nicht sofort offensichtlich, daß wir jeweils einen Interpreter generieren) -

- -
-
-
-
- - - - - - - - -

- wir verzichten auf Introspektion der Elemente -

- -
- - - - - - - - - - -

- denn genau zu diesem Zweck haben wir die "External Tree Description" -

- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- ...d.h, -

-

- kann zusätzlich zu einem anderen Adaptor -

-

- in die Mutator-Dekorator-Kette gehängt werden -

-

- und protokolliert somit "nebenbei" was an Anforderungen an ihm vorbeigeht -

- -
-
-
- - -
- - - - - - - - - - - - - - - - - - - -

- streng genommen ist es nur erlaubt, das ID-Symbol auszuwerten -

- -
- - - - - - - - - - - - - - -

- Visitor bedeutet zwei Indirektionen -

- -
- - - - - -

- ...und das ist nicht akzeptabel für ein reines Selektor-Prädikat! -

- -
-
- - - - - - - - - - - -

- denkbar nur bei Sub-Objekten -

- -
-
- - - - - - - - -

- gilt für alle praktischen Anwendungen -

- -
-
- - - - - - -

- ....auch wenn man zehnmal meinen könnte, -

-

- Kinder eines reinen Wert-Typs wären sinnvoll -- -

-

- sie sind es nicht! -

-

- Jede sinnvolle Entität hat mehr als ein Attribut! -

-

- denn es macht keinen Sinn, Entitäten und reine Wert-Elemente -

-

- auf der gleichen Ebene in der gleichen Sammlung zu mischen. -

-

- -

-

- D.h., entweder man hat ein Objekt, das als Kinder z.B. eine Liste von Strings hat, -

-

- oder man hat eine Entität, die z.b. zwei getypte Objekt-Kinder-Sammlungen hat, -

-

- wie z.B: eine Spur mit Labels und Clips -

- -
-
- - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - -

- "target matches spec" -

- -
- -
- - - - - - - - - - - - - - - -

- aber existiert nominell und kontext-abhängig -

- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- das sind die konkreten Implementierungen -

-

- für spezifische Arten von Bindings -

- -
- - - - - - - - - - - - - - - - -

- kann niemals geschachtelte sub-Mutatoren modellieren -

- -
- - - - - -

- ja wirklich, das wäre nicht sinnvoll!!!!! -

-

- auch wenn man meinen könnte, es geht. -

-

- Grund ist nämlich, es kann jeweils nur ein Onion-Layer für ein gegebenes Element "zuständig" sein. -

-

- Und aus Gründen der logischen Konsistenz darf dieser Diagnose-Layer niemals für ein Element zuständig sein, -

-

- denn sonst würde er es für darunter liegende Layer verschatten. -

- -
- -
-
-
- - - - - - - - - - - - - - - - -

- ⟹ immer Mitwirkung des Elements -

- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- weil beim Assignment die Spec (=GenNode) eben -

-

- zwar die ID des Zieles, aber den neu zuzuweisenden Wert enthält. -

-

- Also wird sich das Ziel nicht anhand des neuen Wertes finden lassen, -

-

- weil es eben grade noch nicht diesen neuen Wert trägt. -

- -
-
- - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- generische Repräsentaton ist so gewählt, -

-

- daß sich alle relevanten Eigenschaften darstellen lassen -

- -
-
- - - - - - -

- wenn also ein Teil der diff-Funkttionalität nicht verfügbar ist, -

-

- dann wird es wohl so sein, daß sie auch nicht gebraucht wird -

- -
- - - - -
- - - - - - -

- zwar erscheint es nicht sonderlich sinnvoll, -

-

- als target auch eine Menge von primitiven Werten zuzulassen. -

-

- -

-

- Es gibt aber auch keinen wirklichen Grund, dies zu verbieten, -

-

- sofern es gelingt, die Funktionalität gutmütig zu degradieren. -

- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- ...will sagen, -

-

- da sind mehrere Layer an praktisch ungebundenem Template-Code dazwischen, -

-

- so daß zu befürchten steht, daß ein unpassendes Lambda erst weit entfernt -

-

- eine womöglich irreführende Meldung generiert -

- -
- -
- - - -
- - - - - - - - - - - - - - - - - - - - - -

- erfordert wirklich Kooperation -

- -
- - - - - - - - - - - - - - -

- ...denn wir verwenden hier als "private" Datenstruktur -

-

- eine etwas komische Collection von Strings, -

-

- in die wir die String-Repräsentation der Spec-Payload schreiben. -

-

- -

-

- In der Praxis dagegen würde man wirklich einen privaten Datentyp verwenden, -

-

- und dann auch voraussetzen, daß man nur Kinder dieses Typs (oder zuweisungskompatibel) bekommt. -

-

- -

-

- Mein Poblem hier ist, daß ich in dieser Demonstrations-Datenstruktur keine nested scopes repräsentieren kann. -

-

- Aber hey!, es ist meine private Datenstruktur -- also kann ich einfach eine Map von nested scopes -

-

- daneben auf die grüne Wiese stellen. Ist ja nur ein Test :-D -

- -
-
-
- - - - - - -

- ...dankenswerterweise hat der subscript-Operator von std::Map -

-

- die nette Eigenschaft, beim ersten Zugriff auf einen neuen Key -

-

- dessen payload per default-konstruktor zu erzeugen. -

- -
- -
-
-
- - - - - - - -

- der Builder in der nested DSL generiert einen sonderbar falschen "this"-Typ, -

-

- genauer gesagt, eine TYPID die falsch ist. -

-

- Und zwar kommt es da zum "Übersprechen" von einem Typ-Parameter in den anderen. -

-

- Im Besonderen hab ich beobachtet, daß, wenn man auf den 3.Typparameter ein Lambda gibt, -

-

- dann auf dem 4. oder 5. Typparameter der bisherige /alte Typ des 3.Typparameters auftaucht, -

-

- u.U auch eingeschachtelt als ein Argument. -

-

- -

-

- Habe mich aber davon überzeugt, daß die eigentlichen Typ-Parameter in Ordnung sind. -

-

- Und zwar habe ich das verifiziert -

-
    -
  • - durch Ausgeben der Typen im Konstruktor (mithilfe meiner typeStr<TY>() -
  • -
  • - durch Einbauen einer Static-Assertion mit Signatur-Match -
  • -
- -
- -
-
- - - - - - - - - - - - - - -

- gemeint ist: -

-

- die native Datenstruktur ist eine Collection von Elementen, -

-

- welche ohne Weiteres direkt in eine GenNode gepackt werden könnten. Denn dann läßt -

-

- sich eine einfache Default-Implementierung des Matchers angeben -

-

- -

-

- Typisches Beispiel: eine STL-Collection von Strings. -

- -
-
- - - - -
-
- - - - - - - - - -

- wir integrieren Attribute nicht, weil es so schön symmetrisch ist, -

-

- sondern weil sie essentiell zum Wesen von Objekten gehören. -

-

- Wenn wir Änderungen an Objekt-Strukturen als Diff erfassen wollen, -

-

- dann müssen Attribute irgendwie sinnvoll integriert sein -

- -
- -
- - - - - - - - - - - - - -

- ⟹ immer in der Klasse verankert -

- -
- -
- - - - - - -

- ⟹ es geht eigentlich nur um den Wert des Attributes -

- -
- -
-
- - - - - - - - - - -

- manche Felder sind optional -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- unter der Maßgabe, -

-

- wie ETD ein Objekt repäsentiert -

- -
- -
- - - - - - - - -

- "Anwendung" : meint das Anwenden eines Diffs auf ein Ziel-Objekt -

-

- "nicht nutzen" : meint ignorieren und verwerfen der Information -

- -
-
- - - - - -
- - - - - - - - - -

- meint: ETD -> Objekt und dann später Objekt -> ETD -

-

- -

-

- warum? -

-

- Weil sich in der ETD die Reihenfolge ändern kann, -

-

- und aber das Aufspielen eines Diffs auf beiden Seiten -

-

- zwingend die gleiche Reihenfolge erfordert! -

- -
-
- - - - - - -

- Objekt -> ETD -> Objekt -

-

- -

-

- warum? -

-

- weil das Quellobjekt keinen Diff erzeugen wird, -

-

- der sich letztlich nicht auf das Zielobjekt aufspielen läßt -

- -
- -
- - - - - - - -

- abweisen, was das Kriterium sicher verletzt -

- -
-
- - - - -
-
- - - - - - - -

- mandatory : Wert muß per Konstruktor gegeben sein -

-

- default : es gibt einen ausgezeichneten Standardwert -

- -
- - - - - - - - -

- das heißt, in dem ins-Verb ist dann ein komplettes Objekt enthalten, -

-

- nicht nur eine leere Record-Hülle, die nachfolgend populiert werden kann (aber nicht muß) -

- -
-
- - - - - - - - - - -

- Konstruktor befüllt das Feld halt irgendwie. -

-

- Ab dem Punkt verhält es sich aber wie ein normales (mandatory) Feld -

- -
-
- - - - - - -

- das Objekt selber kann erkennen, ob das Feld sich im "default-Zustand" befindet -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -

- ohne Prüfen ist emptySrc nicht implementierbar -

- -
- - - - - -

- ...weil es für emptySrc keine neutrale Antwort gibt. -

-

- Denn dieses Prädikat wird von der typischen Implementierung des Diff-Applikators -

-

- in beiden Richtungen verwendet, also sowohl Prüfung auf empty ("expect no further elements"), -

-

- alsauch der Check, daß überhaupt noch Quellelemente anstehen -

- -
-
- - - - - - -

- d.h., man kann nur global auf Prüfung verzichten  -

- -
-
- - - - - - -

- und da habe ich mich bereits dagegen entschieden -

- -
-
- - - - - - - - - - -

- Feld unterstützt default-Wert -

- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - -

- Auslegung der -

-

- Primitiven -

- -
- - - - - - - - - - - - - - -

- rationale: object fields are hard wired, -

-

- thus always available -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- Einschränkung: accept_until END -

- -
- - - - - - -

- ...nämlich indem alle Attribute als "berührt" und akzeptiert markiert werden. -

-

- Somit könnten sofort Zuweisungen als Nächstes passieren -

- -
-
- - - - - - - - -
- - - - - - - - - - - - - - - - - - - - -

- analog wie assignElm -

- -
-
- - - - - - - - - - - - - -

- das heißt, es findet keine Verifikation statt -

- -
-
-
- - - - - - - - - - - - - - - -

- zu bindende -

-

- Operationen -

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- sieht nach Ober-engineering aus, -

-

- zumal das erhebliche Statefulness bewirkt -

- -
- -
- - - - - - - - - - - - - - - - - - - - - - -

- unterstelle Ziel als konstruierbar aus Payload -

- -
-
-
- - - - - - -

- da effektiv bereits der Setter diese Funktionalität enthalten kann und muß, -

-

- denn der Setter nimmt eine GenNode -

- -
- -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -

- injectNew tolerieren -

- -
- - - - - - - -

- ....man könnte genausogut auch beim ersten Mal zuweisen -

- -
-
- - - - - - -

- denn die Diff-Anwendung auf GenNode unterstützt Zuweisung -

-

- ausschließlich bei schon existierenden Elementen. Demnach muß dort auch jedes Attribut -

-
    -
  • - entweder schon mit dem Konstruktor mit gegeben worden sein -
  • -
  • - oder vorher einmal explizit eingefügt -
  • -
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- ...denn wir vermeiden dadurch Komplexität. -

-

- Der gesendete Diff muß einfach passen! -

-

- Genau deshalb haben wir auch in GenNode verschiedene Varianten des gleichen Grundtyps, -

-

- damit wir nicht in die ganzen Ungewissheiten der widening conversions laufen! -

- -
- -
-
-
- - - - - - - - - - - - - - - - -

- d.h. der Attributwert hat Wertsemantik und wird einfach zugewiesen -

- -
-
- - - - - - -

- ...d.h. der Attributwert ist ein Objekt und damit ein nested Scope -

- -
-
- - - - - - - - - -

- Problem: immutable values -

- -
- - - - - - - - - - - - - - - - - - - - - - -

- das alles passiert dann im Lambda -

- -
-
- - -
- - - - - - -

- Dilemma: defaultable fields -

- -
- - - - - - - - - - - - -

- ....mit der ETD, -

-

- bzw der Anwendung des selben Diffs auf eine GenNode-Struktur. -

-

- -

-

- Konsequenz: wenn ein feld defaulted war, und nun explizit gesetzt wird, -

-

- muß dies als INS geschehen, denn eine Zuweisung an nicht aufgeführtes Element ist verboten -

- -
-
- - - - - - - - - -

- folglich ein Problem, -

-

- zu erkennen, wenn wir fertig sind -

- -
-
- - - - - - - - - - - -

- ....weil das defaultable field noch nicht vom Diff berührt wurde. -

-

- Aber es ist kein optional field, d.h. wir haben keine Flag, die es als "defaulted" kennzeichnet -

- -
-
-
- - - - - - - - - - -

- Lösung: alles immer explizit -

- -
- -
-
- - - - - - - - - - - - - - - -

- diese Lösung war zunächst mein Favorit. -

-

- Sie erscheint sehr elegant, weil man im TreeMutator überhaupt nichts dafür tun muß. -

-

- Und die Zusatz-Forderung, daß dann eben das Diff richtig gesendet werden muß, -

-

- erscheint "geschenkt", da wir ohnehin zunächst einmal die Diffs explizit im Code erzeugen. -

-

- -

-

- Aber, nach längerer Überlegung wurde mir der Ansatz mehr und mehr zweifelhaft. -

-

- Das ist die Art von Verkoppelungen, hier die implizite Annahme einer bestimmten Implementierung, -

-

- die ein System unerklärbar und schwer wartbar machen. Das ist die Art von "Features", -

-

- für die man sich nach einiger Zeit entschuldigen muß. -

-

- -

-

- Und noch schlimmer: eigentlich läuft dieser Ansatz darauf hinaus, die Konsistenzprüfung -

-

- am Ende zu deaktivieren. Nur wir machen das nicht explizit, sondern durch die Hintertür. -

-

- Also dann besser klar und ehrlich! -

- -
- -
-
- - - - - - - - - -

- ...denn unter dem Strich würden wir hiermit volle Unterstützung für opitonale Attribute einführen, -

-

- also eine Attribut-Semantik auf eine Feld-Semantik draufpflanzen. -

-

- Aber in der vorausgegangenen Analyse habe ich mich schon davon überzeugt, -

-

- daß wir keine Attribut-Semantik brauchen. Und wenn doch, dann bietet das Diff-System -

-

- immer noch die Möglichkeit, die Attribute explizit als Sammlung darzustellen. -

- -
- -
-
- - - - - - -

- auf die empty-Prüfung am Ende verzichten -

- -
- - -
-
-
- - - - - - - - - -

- denn in den meisten, wichtigsten Fällen get es um einen non-empty-check, -

-

- bevor ein anderes Verifikations-Prädikat angewendet wird. -

- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- jedwede "bessere" Implementierung muß zwingend einen Container verwenden, -

-

- der dann die Lambdas für die einzelnen Setter auf den Heap legt. -

-

- Das ist hier tatsächlich viel schlechter, als das bischen lineare Suche -

- -
-
-
-
-
- - - - - - - - -

- ....durch meinen allerersten Draft, -

-

- für den ich damals gezwungen war, die GenNode zu erfinden :) -

- -
- - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- gleiches Argument... -

- -
-
- - - - - - -

- ...damit unterstellen wir, daß später eine Symbol-Tabelle aufgebaut wird. -

-

- Dann kann man sich immer noch überlegen, ob man dann an dieser Stelle bereinigt -

- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- in einem Fall kann man sie aus der Closure abgreifen -

-

- im anderen Fall muß es doch der Client leisten. -

-

- Keine klare Linie -

- -
- -
- - - - - - - - - - -

- ...das heißt, es gibt nur minimale, themantische Überlappung. -

-

- Also ist die Verwendung von Vererbung hier sogar die beste Lösung -

- -
- -
- - - - - - -

- Geschachtelte Typdefs lassen sich vermeiden: -

-

- BareEntryID speichern! -

- -
- -
- - - - - - -

- ...das heißt, wie rum man es auch auflöst, wird die Lösung auf einer Seite schlechter -

-
    -
  • - wenn wir für den Payload-Typ einen Typ-Parameter nehmen, blähen wir den Standard-Fall (Setter) auf -
  • -
  • - andererseits ist es unbstreitbar einfach so, daß für den Mutator-Builder die Typisierung komplett implizit ist, das muß die Closure mit sich selbst ausmachen, einfach indem in der Closure ein geschachtelter TreeMutator konstruiert wird, der eben mit diesem impliziten Kind-Typ umgehen kann. -
  • -
  • - wenn wir stattdessen nur einen Key-String speichern, wird zum Einen die Match-Prüfung aufwendiger (Stringvergleich statt Vergleich von Hashes), und außerdem wird ein Typ-Mismatch nicht mehr auf der Ebene der Verb-Anwendung entdeckt und entsprechend gekennzeichnet, sondern wir hoffen, daß es dann innerhalb der Closure zu einem Fehlzugriff auf die Payload der GenNode kommt. Noch schlimmer im Mutator-Fall, da sind wir dann schon im geschachtelten Scope und hoffen, daß dann der eingeschachtelte Mutator irgendwo auf Widerspruch läuft. -
  • -
- -
- -
- - - - - - -

- ...gedacht für verschiedene UseCases. -

-
    -
  • - Fall 1: String-Key und der Typ muß irgendwie implizit/explizit gegeben sein -
  • -
  • - Fall2: GenNodeID -
  • -
- -
- -
- - - - - - -

- ...die offensichtlichsten Dinge übersieht man nur zu leicht!!!!! -

-

- Da es ein nested scope ist, ist es immer ein Objekt, -

-

- also repräsentiert als Rec<GenNode> -

- -
- -
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- zwei Bindings -

- -
- - - - - - -
- - - - - - - - - - - - - -

- zwei Collection-Bindings -

- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- ...diese Abkürzung ist nur auf den Konstruktur aufgepflanzt, -

-

- nicht aber in der eigentlichen Implementierung verankert. -

-

- Das wollte ich nicht, weil ich längerfristig doch davon ausgehe, -

-

- daß es einfach einen Metadaten-Scope gibt -

-

- -

-

- Die Inkonsequenz nun ist, daß im Rec::Mutator keine Magie dafür vorgesehen ist -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -

- ...mit den Lambdas kann ich nur die Sicht auf die Werte steuern, -

-

- nicht aber das eigentliche Verhalten des Bindings. -

-

- -

-

- Denn die Lambdas haben keinen Zugriff auf die Ziel-Datenstruktur! -

- -
- -
- - - - - - - - - - - - - - - - - - - - - - -

- ...wir wollen mehrfach geschichtete TreeMutator-Subklassen, -

-

- aber tatsächlich liefert jeder DSL-Aufruf einen Builder<TreeMutator<...>>. -

-

- Die normalen DSL-Aufrufe sind eben genau so gestrickt, daß jeweils der oberste Builder entfernt wird, -

-

- ein neuer Layer darübergebaut und das Ganze wieder in einen Builder eingewickelt wird. -

-

- -

-

- Dadurch ist es schwer bis unmöglich (wg. den Lambdas), den resultierenden Typ anzuschreiben. -

-

- Daher bin ich zwingend auf Wrapper-Funktionen angewiesen, die diesen resultierenden Typ -

-

- vom konkreten Aufruf wieder "abgreifen". Ich kann daher nicht die DSL-Notation verwenden, -

-

- um den Dekorator für die Behandlung des Typ-Feldes einzubringen. -

- -
-
-
-
-
-
- - - - - - - - - - -

- Mut -> Rekursion -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- Problem: partielle Ordnung -

- -
- - - - - - - - - - - - - -

- ...das heißt, -

-

- das AFTER-Verb wird übersetzt in ein skip_until, -

-

- und das läuft dann entweder in jedem Layer -

-

- oder nur in dem Layer, der auf die Spec paßt. -

-

- In jedem Fall gerät dadurch die relative Verzahnung der Elemente untereinander aus dem Takt -

- -
-
- - - - - - - -

- ...das heißt also, es wird stets der zuerst gebundene Layer komplett durchgespult, -

-

- gefolgt dann von dem nächsten Layer. -

-

- -

-

- Die Konsequenz ist, daß es keine Mischung der Typen geben kann. -

-

- Es müssen immer zwingend alle Elemente eines Typs von einem Layer behandelt werden -

-

- und diese Elemente müssen geschlossen hintereinander in der Reihenfolge liegen -

- -
-
-
-
-
-
- - - - - - - - -

- auf Basis des neu geschaffenen TreeMutators -

- -
- - - - - - - - - - -

- ....man könnte später geeignete Automatismen schaffen, -

-

- die sich diesen TreeMutator beschaffen -

-
    -
  • - indem erkannt wird, daß das eigentliche Zielobjekt ein bestimmtes API bietet -
  • -
  • - indem andere relevante Eigenschaften des Zielobjekts erkannt werden -
  • -
- -
- - -
- - - - - - -

- ...das so häufig in C++ auftretende Problem: -

-

- wie baue und verwalte ich eine konkrete Implementierung, -

-

- ohne gleich ein ganzes Management-Framework einführen zu müssen. -

-

- Letzten Endes lief  das auch in diesem Fall auf inline-Storage hinaus... -

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- ....daß ein unbedarfter client diesen Trick übershieht -

-

- und daher den Rückgabewert wegwirft. -

-

- -

-

- Argument: we soweit einsteigt, die Metaprogramming-Lösung zu nutzen, -

-

- sollte auch intelligent genug sein, die API-Doc zu lesen. -

-

- -

-

- Standard == Interface DiffMutable implementieren -

- -
- -
-
- - - - - - - - - - - -

- Client soll direkt mutatorBinding bieten -

- -
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - -

- nicht generisch: mutatorBinding -

- -
- -
-
- - - - - - -

- Lösungsversuch: extern template -

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- ...im Klartext: diesen Zugriff von der generischen Implementierung -

-

- auf den eingebauten Stack-Mechanismus benötigen wir nur... -

-
    -
  • - einmal zu Beginn, bei der Konstruktion -
  • -
  • - wenn wir in einen geschachtelten Scope eintreten -
  • -
  • - wenn wir einen Solchen verlassen -
  • -
-

- Zwar sind indirekte Calls aufwendiger, aber letzten Endes auch wieder nicht soooo aufwendig, -

-

- daß sie uns im gegebenen Kontext umbringen... -

- -
- -
-
- - - - - - - - - - - - -

- intern: eingebaute initDiffApplication() -

- -
- - - - - -

- ...wird automatisch vor Konsumieren eines Diff aufgerufen -

- -
-
- - - - - - -

- Widerspruch: TreeMutator ist Wegwerf-Objekt -

- -
- -
- - - - -
-
- - - - - - -

- Lösungsversuch: doppelte Hülle -

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -

- kann daher TreeMutator konstruieren -

- -
-
- - - - - - -

- ...und zwar per mutatorBinding -

- -
-
- - - - - - -

- implementiert somit initDiffApplication() -

- -
-
-
-
- - - - - - -

- TODO: Namensgebung -

- -
- - - - - - - - - - -
-
- - - - - - - - - - - -

- TreeMutator-Binding muß opaque bleiben -

- -
-
- - - - - - -

- Buffer-Größen-Management vorsehen -

- -
- - - - - - - - -

- das heißt -

-
    -
  • - ein sinnvoller Startwert wird heuristisch vorgegeben -
  • -
  • - wenn die Allokation scheitert, die Exception fangen und die tatsächlich benötigte Größe merken -
  • -
- -
-
- - - - - - - - - - - - - - - -

- ...das heißt: -

-

- gegeben ein syntaktisch sinnvoller top-level-Aufruf ("wende das Diff an") -

-

- -- wie bzw. von wem bekommen wir dann ein Binding, das einen passenden TreeMutator konstruiert? -

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- erscheint mir die am wenigsten überraschende Lösung. -

-

- und zwar per handle.get() -

- -
- -
- - - - - - - -

- erscheint mir fehleranfällig und irreführend für den Nutzer der Schnittstelle. -

-

- Denn er muß zwar das Objekt in das Handle platzieren, dann aber auch noch einen Pointer zurückgeben, -

-

- der dann auch noch NULL sein kann, zum Signalisieren von Fehlern. -

-

- Ich empfinde das als schlechten Stil -

- -
- -
- - - - - - -

- naja, das wäre billig, aber auch wieder beliebig. -

-

- Es macht keinen Sinn vom API-Design her, sondern man müßte es halt machen, -

-

- weil die Implementierung den Zeiger auf den geschachtelen sub-Mutator umsetzen muß. -

- -
- -
-
-
- - - - - - - - - - - - -

- die Diff-Sprache verlangt, -

-

- daß vor dem Öffnen des geschachtelten Scopes -

-

- dieser zumindest einmal per ins "angelegt" wurde. -

- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - -

- ...das ist ein Versuch, den Code für den Leser verständlich zu halten. -

-

- Die Idee ist, daß es einen high-level Unit-Test gibt, der die gesamte Diff-Anwendung durchspielt -

-

- und dazu passend einen low-level Unit-Test, der analog die gleichen Operationen macht, -

-

- allerdings direkt auf dem TreeDiff-Interface durch Aufruf der passenden Primitiv-Operaionen. -

-

- Letztere müssen für jede Art von "onion-layer" (konkretes Binding) erneut implementiert -

-

- und daher auch jeweils eigens per Unit-Test abgedeckt werden. -

- -
-
- - - - - - -

- das ist hier sinnvoll. Das Binding sollte komplexer sein, -

-

- als in der Praxis auftretende Bindings. Warum? Weil letztere immer etwas einseitg sind -

-

- und damit Abkürzungen im Code-Pfad ausnützen. Die Gefahr schlummert aber im Zusammenspiel -

-

- der konkreten Bindings mit mehreren "onion layers"! -

- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - -

- ...denn es ist sehr verwirrend, welche Signatur denn nun die Lambdas haben müssen -

- -
- - -
- - - - - - -

- ...denn es kann keinen Default-Matcher geben.... -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - -

- ...sonst wird niemand Lambdas bereitstellen können, oder gar Diff-Nachrichten erzeugen. -

-

- Das ist nun kein spezielles Problem der gewählten Implementierungs-Technik, sondern rührt daher, -

-

- daß der Client hier eigentlich ein Protokoll implementieren muß. -

- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- wenn überhaupt, dann im Matcher im Binding-Layer implementieren -

- -
- -
- - - - - - -

- ...denn wir haben nun mehrere Layer, -

-

- und der Selector kann einfach anhand von Ref::THIS keine sinnvolle Entscheidung treffen. -

-

- Daher versuchen dann alle Layer dieses Element zu behandeln, oder gar keiner -

-

- -

-

- Und da der Selector nur die Spec anschauen darf, läßt sich das auch nachher nicht mehr korrigieren -

-

- -

-

- Daher habe ich mich entschlossen, dieses Sprachkonstrukt zu entfernen -

- -
-
- - - - - - -

- entfernt, da schlechtes Design -

- -
-
-
- - - - - - - - - - - -

- entfernt, da schlechtes Design -

- -
-
-
-
-
- - - - - - - - - - - - - - - - - - - -

- anscheinend nicht notwendig -

- -
- -
- - - - - - -
-
-
-
- + + + @@ -34343,7 +31021,7 @@ - + @@ -34358,7 +31036,8 @@ - + + @@ -34390,7 +31069,7 @@ - + @@ -34542,7 +31221,7 @@ - + @@ -34555,7 +31234,8 @@ Der Nexus speichert nämlich eine direkte Referenz in der Routingtabelle

-
+ +
@@ -34566,157 +31246,10 @@ - + + + - - - - - - - - - - -
    -
  • - Map hat kein emplace_back -
  • -
  • - Map hat kein back() -
  • -
-

- Beides ist erst mal sinnvoll. Map hat zwar ein emplace, aber das fügt eben irgendwo ein -

-

- Und es gibt nicht sowas wie das "zuletzt behandelte" Element -

- -
- -
- - - - - - - - - - - - - - - - - - - -

- Reihenfolge -

-

- erhalten! -

- -
- - - - - - - - - - - - - - -

- ...hat eine "zufällige" Reihenfolge, die von den Hash-Werten der gespeicherten Daten abhängt. -

-

- Das bricht mit unserem grundsätzlichen Konzept der kongruenten  Daten-Strukturen -

- -
- -
- - - - - - -

- Ein Diff, das von einer ETD gezogen wurde, -

-

- läßt sich nicht auf eine Map-Implementierung aufspielen -

- -
- -
-
-
- - - - - - -

- Entscheidung -

- -
- - - - - - - - - - - - - -

- ...zum Beispiel wie grade hier, beim MockElm -

-

- das wird vermutlich niemals wirklich in einem vollen Diff-Zusammenhang gebraucht. -

-

- -

-

- Und dann ist unbestreitbar eine Map eine sehr einfache Implementierung -

-

- und auch im Diff-Applikator nicht wirklich schwierig zu unterstützen -

- -
- -
- - - - - - - - -
@@ -34779,7 +31312,7 @@ - + @@ -34792,7 +31325,8 @@ da im Übrigen das UI-Modell nur mit LUIDs und generischen Namen arbeitet

-
+ +
@@ -34869,7 +31403,7 @@ - + @@ -34879,7 +31413,8 @@ ...was ich einen Monat später schon wieder vergessen hatte...

-
+ +
@@ -34913,7 +31448,7 @@ - + @@ -34941,14 +31476,15 @@ das reicht für die erste Integrationsrunde völlig aus

-
+ +
- + @@ -34958,7 +31494,8 @@ Instanz-Management ist automatisch

-
+ +
@@ -35332,7 +31869,7 @@ - + @@ -35357,7 +31894,8 @@ denn hier nun läuft tatsächlicher Code aus dem Destruktor heraus!

-
+ +
@@ -35367,7 +31905,7 @@ - + @@ -35383,12 +31921,13 @@ über den Core-Service, der Nexus nach dem Nexus....

-
+ +
- + @@ -35398,7 +31937,8 @@ ich will nicht damit anfangen, daß man einen Zeiger umsetzen kann....

-
+ +
@@ -35439,7 +31979,7 @@ - + @@ -35457,7 +31997,8 @@ - + + @@ -35465,7 +32006,7 @@ - + @@ -35481,7 +32022,8 @@ match("a").after("b") scheitert, weil sich die Suche am ersten "a" festbeißt.

-
+ +
@@ -35503,7 +32045,7 @@ - + @@ -35549,7 +32091,8 @@          ^~~~~~~~~~

-
+ +
@@ -35558,7 +32101,7 @@ - + @@ -35582,7 +32125,8 @@ - + + @@ -35599,7 +32143,7 @@ - + @@ -35616,7 +32160,7 @@ - + @@ -35629,11 +32173,12 @@ Implementierung der real-world-Variante fehlt!

-
+ + - + @@ -35649,7 +32194,8 @@ wie Session- und State-Managment, Commands etc.

-
+ +
@@ -35940,7 +32486,7 @@ - + @@ -35956,7 +32502,8 @@ und ebenso die Gesten abstrahieren

-
+ +
@@ -35973,7 +32520,7 @@ - + @@ -36001,7 +32548,8 @@ - + + @@ -36016,7 +32564,7 @@ - + @@ -36035,7 +32583,8 @@ sondern gegen eine Abstraction (Command), die eigens dafür geschaffen wurde

-
+ +
@@ -36092,7 +32641,7 @@ - + @@ -36110,13 +32659,14 @@ - + + - + @@ -36126,7 +32676,8 @@ ...da die DispatcherQueue direkt Command-Objekte (=frontend handle) speichert

-
+ +
@@ -36135,7 +32686,7 @@ - + @@ -36154,7 +32705,8 @@ und wenn es stirbt, dann stirbt es halt...

-
+ +
@@ -36174,7 +32726,7 @@ - + @@ -36184,7 +32736,8 @@ aufruf direkt mit Command-ID -> erzeugt automatisch eine Klon-Kopie

-
+ +
@@ -36247,7 +32800,7 @@ - + @@ -36263,13 +32816,14 @@ automatisch die Kontext-Accessor-Ausdrücke ausgewertet werden

-
+ +
- + @@ -36285,12 +32839,13 @@ mit dem InteractionDirector verdrahtet sein muß!

-
+ + - + @@ -36303,9 +32858,10 @@ und auch nichts mit der Trennung zwischen Layern und Subsystemen

-
+ +
- + @@ -36318,13 +32874,14 @@ aka DependencyInjection + Lifecycle Management

-
+ + - + @@ -36345,7 +32902,8 @@ - + + @@ -36358,7 +32916,7 @@ - + @@ -36371,10 +32929,11 @@ es könnte auch ausreichen, einfach die passende InteractionStateManager-Impl zu verwenden

-
+ +
- + @@ -36384,11 +32943,12 @@ denn InteractionStateManager ist ein Interface!

-
+ +
- + @@ -36407,9 +32967,10 @@ Das könnte ein Advice sein

-
+ +
- + @@ -36428,9 +32989,10 @@ In diesem Fall wird das Command enabled

-
+ +
- + @@ -36440,9 +33002,10 @@ eine Argumentliste mit mehreren Parametern wir Schritt für Schritt geschlossen

-
+ +
- + @@ -36455,7 +33018,8 @@ wird das gemäß Scope "nächstgelegne" genommen

-
+ +
@@ -36561,7 +33125,7 @@ - + @@ -36571,12 +33135,13 @@ die Instanz kommt nicht in der Fixture-Queue an

-
+ +
- + @@ -36589,9 +33154,10 @@ gehört nicht zum Thema "Instanz-Management"

-
+ +
- + @@ -36607,7 +33173,8 @@ schon "in der Mache ist"

-
+ +
@@ -36627,7 +33194,7 @@ - + @@ -36655,7 +33222,8 @@ neues Command-Objekt kopiert wird. Was allerdings den RefCount erhöht.

-
+ +
@@ -36667,7 +33235,7 @@ - + @@ -36677,7 +33245,8 @@ aber sich mit einem Refcount verrückt machen.....

-
+ +
@@ -36689,7 +33258,7 @@ - + @@ -36705,9 +33274,10 @@ mithin in der GenNode::ID

-
+ +
- + @@ -36729,7 +33299,8 @@ in der globalen Registry

-
+ + @@ -36768,7 +33339,7 @@ - + @@ -36781,9 +33352,10 @@ und die Form der ID-Dokoration zur Konvention machen

-
+ +
- + @@ -36808,9 +33380,10 @@ Das wollte ich genau nicht

-
+ +
- + @@ -36839,7 +33412,8 @@ da es letztlich nur darum geht ein ohnehin öffentliches  Interface aufzurufen

-
+ +
@@ -36861,7 +33435,7 @@
- + @@ -36874,7 +33448,8 @@ und unsinnigerweise aufwendig

-
+ +
@@ -37049,7 +33624,7 @@
- + @@ -37067,7 +33642,8 @@ - + + @@ -37129,7 +33705,7 @@ - + @@ -37148,7 +33724,8 @@ und mit einfachen, direkt gegebenen Objekten

-
+ +
@@ -37223,7 +33800,7 @@ - + @@ -37236,9 +33813,10 @@ (Beispiel "in-point fehlt")

-
+ +
- + @@ -37254,7 +33832,8 @@ aber von einem externen State-Change getriggert wird

-
+ +
@@ -37280,7 +33859,7 @@ - + @@ -37293,7 +33872,8 @@ Insofern löst sich dieser Knoten langsam

-
+ +
@@ -37322,7 +33902,7 @@ - + @@ -37341,7 +33921,8 @@ Oder man könnte sie anonym verarbeiten, weil Command selber ein smart-Handle ist.

-
+ +
@@ -37361,7 +33942,7 @@
- + @@ -37377,7 +33958,8 @@ CommandID.KontextID == Instanz

-
+ + @@ -37456,7 +34038,7 @@ - + @@ -37472,7 +34054,8 @@ Nebenläufigkeit ist kein Argument (da das UI single-threaded läuft)

-
+ +
@@ -37556,7 +34139,7 @@ - + @@ -37575,7 +34158,8 @@ oder ein Command an den Dispatcher übergeben...

-
+ + @@ -37647,7 +34231,7 @@ - + @@ -37663,9 +34247,10 @@ Den kann man aber mit geeigneter Syntax auch direkt angeben

-
+ +
- + @@ -37678,7 +34263,8 @@ allein dafür genügt eine GenNode

-
+ +
@@ -37789,7 +34375,7 @@ - + @@ -37805,12 +34391,13 @@ Also genügt es, einen anonymen Klon dieser Instanz zu halten

-
+ +
- + @@ -37832,7 +34419,8 @@ Beispiel: Menü-Eintrag "create duplicate"

-
+ + @@ -37849,7 +34437,7 @@
- + @@ -37871,7 +34459,8 @@ oder andernfalls einen bestimmten Namen bekommt

-
+ + @@ -37895,7 +34484,7 @@ - + @@ -37914,7 +34503,8 @@ wieder komplett zurückgebaut habe

-
+ +
@@ -37978,7 +34568,7 @@ - + @@ -37996,7 +34586,8 @@ - + + @@ -38082,7 +34673,7 @@ - + @@ -38095,13 +34686,14 @@ während bereits die nächste Instanz für das GUI ausgegeben wurde.

-
+ +
- + @@ -38111,7 +34703,8 @@ ...damit die Nummer erhalten bleibt

-
+ +
@@ -38150,7 +34743,7 @@ - + @@ -38163,11 +34756,12 @@ wenn wir context-bound -Commands verwenden

-
+ +
- + @@ -38183,7 +34777,8 @@ deshalb ist auch der UI-Bus nicht das Universal-Interface schlechthin

-
+ +
@@ -39381,9 +35976,77 @@ - + + + + + + + +

+ und zwar etwas wirklich Einfaches +

+ + +
+
+ + + + + + +

+ denn "elementar" bedeutet in diesem Fall, es wird ziemlich technisch und komplex +

+ + +
+
+
+ + + + + + + + +

+ oh ja.... +

+

+ das war ziemlich halbgar, und wäre früher oder später ganz übel in's Auge gegangen. +

+

+ +

+

+ Erinnere mich, daß ich damals beim Einführen des MockElm dann eben doch eine »Attribute-Map« gebaut habe, obwohl ich vorher mich eigentlich gegen dieses Konzept entschieden hatte. Es ist in der Praxis dann doch manchmal sinnvolle, wie dieser Fall zeigt. Damit wurde aber mein TreeMutator-Collection-Binding "wackelig", und ich hab mich da mehr oder weniger durchgefrickelt. +

+

+ +

+

+ Jetzt gibt es also echte ContainerTraits, und damit ist der Aufbau zukunftsfest. +

+ + +
+ +
+ + + + + + + + + +
@@ -39419,6 +36082,161 @@
+ + + + + + + + + + + + + + + +
    +
  • + Map hat kein emplace_back +
  • +
  • + Map hat kein back() +
  • +
+

+ Beides ist erst mal sinnvoll. Map hat zwar ein emplace, aber das fügt eben irgendwo ein +

+

+ Und es gibt nicht sowas wie das "zuletzt behandelte" Element +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + +

+ Reihenfolge +

+

+ erhalten! +

+ +
+ + + + + + + + + + + + + + +

+ ...hat eine "zufällige" Reihenfolge, die von den Hash-Werten der gespeicherten Daten abhängt. +

+

+ Das bricht mit unserem grundsätzlichen Konzept der kongruenten  Daten-Strukturen +

+ +
+ +
+ + + + + + +

+ Ein Diff, das von einer ETD gezogen wurde, +

+

+ läßt sich nicht auf eine Map-Implementierung aufspielen +

+ +
+ +
+
+
+ + + + + + +

+ Entscheidung +

+ +
+ + + + + + + + + + + + + +

+ ...zum Beispiel wie grade hier, beim MockElm +

+

+ das wird vermutlich niemals wirklich in einem vollen Diff-Zusammenhang gebraucht. +

+

+ +

+

+ Und dann ist unbestreitbar eine Map eine sehr einfache Implementierung +

+

+ und auch im Diff-Applikator nicht wirklich schwierig zu unterstützen +

+ +
+ +
+ + + + + + + + + +
@@ -40111,7 +36929,7 @@ - + @@ -40246,7 +37064,8 @@ - + + @@ -40262,7 +37081,7 @@ - + @@ -40296,7 +37115,7 @@ - + @@ -40455,8 +37274,3786 @@ - + + + + + + + + + + + + + + + + + + + +
    +
  • + Diff-Anwendung wird massiv und in der Breite stattfinden +
  • +
  • + sie wird als Reaktion auf UI-Events auftreten +
  • +
  • + sie dient dazu, andere UI-Operationen einzusparen +
  • +
  • + also muß speziell das Traversieren bis an den Anwendungsort bedacht werden +
  • +
+ +
+
+ + + + + + +

+ ...d.h. die bis jetzt geschriebene TreeApplikator-Implementierung +

+

+ ist erstaunlich leichtgewichtig. Zu den zwei Indirektionien der Sprache +

+

+ kommt nur entweder ein weiterer aus der GenNode bzw stattedessen ein dynamic cast hinzu. +

+

+ Alles andere steckt in dem expliziten Mutator-Typ +

+

+  -- das gibt einen wichtigen Hinweis -- +

+ +
+
+ + + + + + +

+ ...da wir eine verb-basierte Sprache implementieren, +

+

+ also einen double-dispatch haben +

+ +
+
+ + + + + + + + + + + + +

+ weil wir den Anwendungs-Kontext noch überhaupt nicht kennen. +

+

+ Man könnte also später, wenn das ganze System "steht", +

+

+ das Diff-System noch einmal reimplementieren, dann mit einem vorgegebenen Diff-Typ +

+ +
+
+
+ + + + + + +

+ Beschluß: akzeptiert +

+ +
+ +
+
+ + + + + + + + +

+ im Sinn von "polymorpic value" ist das Backend virtuell +

+ +
+
+ + + + + + + + + +

+ ....wenngleich auch dieser aus einem Template generiert wird +

+

+ (will sagen, es ist nicht sofort offensichtlich, daß wir jeweils einen Interpreter generieren) +

+ +
+
+
+
+ + + + + + + + +

+ wir verzichten auf Introspektion der Elemente +

+ +
+ + + + + + + + + + +

+ denn genau zu diesem Zweck haben wir die "External Tree Description" +

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ ...d.h, +

+

+ kann zusätzlich zu einem anderen Adaptor +

+

+ in die Mutator-Dekorator-Kette gehängt werden +

+

+ und protokolliert somit "nebenbei" was an Anforderungen an ihm vorbeigeht +

+ +
+
+
+ + +
+ + + + + + + + + + + + + + + + + + + +

+ streng genommen ist es nur erlaubt, das ID-Symbol auszuwerten +

+ +
+ + + + + + + + + + + + + + +

+ Visitor bedeutet zwei Indirektionen +

+ +
+ + + + + +

+ ...und das ist nicht akzeptabel für ein reines Selektor-Prädikat! +

+ +
+
+ + + + + + + + + + + +

+ denkbar nur bei Sub-Objekten +

+ +
+
+ + + + + + + + +

+ gilt für alle praktischen Anwendungen +

+ +
+
+ + + + + + +

+ ....auch wenn man zehnmal meinen könnte, +

+

+ Kinder eines reinen Wert-Typs wären sinnvoll -- +

+

+ sie sind es nicht! +

+

+ Jede sinnvolle Entität hat mehr als ein Attribut! +

+

+ denn es macht keinen Sinn, Entitäten und reine Wert-Elemente +

+

+ auf der gleichen Ebene in der gleichen Sammlung zu mischen. +

+

+ +

+

+ D.h., entweder man hat ein Objekt, das als Kinder z.B. eine Liste von Strings hat, +

+

+ oder man hat eine Entität, die z.b. zwei getypte Objekt-Kinder-Sammlungen hat, +

+

+ wie z.B: eine Spur mit Labels und Clips +

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ "target matches spec" +

+ +
+ +
+ + + + + + + + + + + + + + + +

+ aber existiert nominell und kontext-abhängig +

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ das sind die konkreten Implementierungen +

+

+ für spezifische Arten von Bindings +

+ +
+ + + + + + + + + + + + + + + + +

+ kann niemals geschachtelte sub-Mutatoren modellieren +

+ +
+ + + + + +

+ ja wirklich, das wäre nicht sinnvoll!!!!! +

+

+ auch wenn man meinen könnte, es geht. +

+

+ Grund ist nämlich, es kann jeweils nur ein Onion-Layer für ein gegebenes Element "zuständig" sein. +

+

+ Und aus Gründen der logischen Konsistenz darf dieser Diagnose-Layer niemals für ein Element zuständig sein, +

+

+ denn sonst würde er es für darunter liegende Layer verschatten. +

+ +
+ +
+
+
+ + + + + + + + + + + + + + + + +

+ ⟹ immer Mitwirkung des Elements +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ weil beim Assignment die Spec (=GenNode) eben +

+

+ zwar die ID des Zieles, aber den neu zuzuweisenden Wert enthält. +

+

+ Also wird sich das Ziel nicht anhand des neuen Wertes finden lassen, +

+

+ weil es eben grade noch nicht diesen neuen Wert trägt. +

+ +
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ generische Repräsentaton ist so gewählt, +

+

+ daß sich alle relevanten Eigenschaften darstellen lassen +

+ +
+
+ + + + + + +

+ wenn also ein Teil der diff-Funkttionalität nicht verfügbar ist, +

+

+ dann wird es wohl so sein, daß sie auch nicht gebraucht wird +

+ +
+ + + + +
+ + + + + + +

+ zwar erscheint es nicht sonderlich sinnvoll, +

+

+ als target auch eine Menge von primitiven Werten zuzulassen. +

+

+ +

+

+ Es gibt aber auch keinen wirklichen Grund, dies zu verbieten, +

+

+ sofern es gelingt, die Funktionalität gutmütig zu degradieren. +

+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ ...will sagen, +

+

+ da sind mehrere Layer an praktisch ungebundenem Template-Code dazwischen, +

+

+ so daß zu befürchten steht, daß ein unpassendes Lambda erst weit entfernt +

+

+ eine womöglich irreführende Meldung generiert +

+ +
+ +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + +

+ erfordert wirklich Kooperation +

+ +
+ + + + + + + + + + + + + + +

+ ...denn wir verwenden hier als "private" Datenstruktur +

+

+ eine etwas komische Collection von Strings, +

+

+ in die wir die String-Repräsentation der Spec-Payload schreiben. +

+

+ +

+

+ In der Praxis dagegen würde man wirklich einen privaten Datentyp verwenden, +

+

+ und dann auch voraussetzen, daß man nur Kinder dieses Typs (oder zuweisungskompatibel) bekommt. +

+

+ +

+

+ Mein Poblem hier ist, daß ich in dieser Demonstrations-Datenstruktur keine nested scopes repräsentieren kann. +

+

+ Aber hey!, es ist meine private Datenstruktur -- also kann ich einfach eine Map von nested scopes +

+

+ daneben auf die grüne Wiese stellen. Ist ja nur ein Test :-D +

+ +
+
+
+ + + + + + +

+ ...dankenswerterweise hat der subscript-Operator von std::Map +

+

+ die nette Eigenschaft, beim ersten Zugriff auf einen neuen Key +

+

+ dessen payload per default-konstruktor zu erzeugen. +

+ +
+ +
+
+
+ + + + + + + +

+ der Builder in der nested DSL generiert einen sonderbar falschen "this"-Typ, +

+

+ genauer gesagt, eine TYPID die falsch ist. +

+

+ Und zwar kommt es da zum "Übersprechen" von einem Typ-Parameter in den anderen. +

+

+ Im Besonderen hab ich beobachtet, daß, wenn man auf den 3.Typparameter ein Lambda gibt, +

+

+ dann auf dem 4. oder 5. Typparameter der bisherige /alte Typ des 3.Typparameters auftaucht, +

+

+ u.U auch eingeschachtelt als ein Argument. +

+

+ +

+

+ Habe mich aber davon überzeugt, daß die eigentlichen Typ-Parameter in Ordnung sind. +

+

+ Und zwar habe ich das verifiziert +

+
    +
  • + durch Ausgeben der Typen im Konstruktor (mithilfe meiner typeStr<TY>() +
  • +
  • + durch Einbauen einer Static-Assertion mit Signatur-Match +
  • +
+ +
+ +
+
+ + + + + + + + + + + + + + +

+ gemeint ist: +

+

+ die native Datenstruktur ist eine Collection von Elementen, +

+

+ welche ohne Weiteres direkt in eine GenNode gepackt werden könnten. Denn dann läßt +

+

+ sich eine einfache Default-Implementierung des Matchers angeben +

+

+ +

+

+ Typisches Beispiel: eine STL-Collection von Strings. +

+ +
+
+ + + + +
+ + + + + + + + + +

+ das heißt, wir können Elemente in der gleichen Reihenfolge anfügen, in der sie später dann in der Iteration erscheinen +

+ +
+ +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
    +
  • + Map hat kein emplace_back +
  • +
  • + Map hat kein back() +
  • +
+

+ Beides ist erst mal sinnvoll. Map hat zwar ein emplace, aber das fügt eben irgendwo ein +

+

+ Und es gibt nicht sowas wie das "zuletzt behandelte" Element +

+ +
+ + + + + + + + +

+ MockElm, Z 260 : .attach (collection(attrib) +

+ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ wir integrieren Attribute nicht, weil es so schön symmetrisch ist, +

+

+ sondern weil sie essentiell zum Wesen von Objekten gehören. +

+

+ Wenn wir Änderungen an Objekt-Strukturen als Diff erfassen wollen, +

+

+ dann müssen Attribute irgendwie sinnvoll integriert sein +

+ +
+ +
+ + + + + + + + + + + + + +

+ ⟹ immer in der Klasse verankert +

+ +
+ +
+ + + + + + +

+ ⟹ es geht eigentlich nur um den Wert des Attributes +

+ +
+ +
+
+ + + + + + + + + + +

+ manche Felder sind optional +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ unter der Maßgabe, +

+

+ wie ETD ein Objekt repäsentiert +

+ +
+ +
+ + + + + + + + +

+ "Anwendung" : meint das Anwenden eines Diffs auf ein Ziel-Objekt +

+

+ "nicht nutzen" : meint ignorieren und verwerfen der Information +

+ +
+
+ + + + + +
+ + + + + + + + + +

+ meint: ETD -> Objekt und dann später Objekt -> ETD +

+

+ +

+

+ warum? +

+

+ Weil sich in der ETD die Reihenfolge ändern kann, +

+

+ und aber das Aufspielen eines Diffs auf beiden Seiten +

+

+ zwingend die gleiche Reihenfolge erfordert! +

+ +
+
+ + + + + + +

+ Objekt -> ETD -> Objekt +

+

+ +

+

+ warum? +

+

+ weil das Quellobjekt keinen Diff erzeugen wird, +

+

+ der sich letztlich nicht auf das Zielobjekt aufspielen läßt +

+ +
+ +
+ + + + + + + +

+ abweisen, was das Kriterium sicher verletzt +

+ +
+
+ + + + +
+
+ + + + + + + +

+ mandatory : Wert muß per Konstruktor gegeben sein +

+

+ default : es gibt einen ausgezeichneten Standardwert +

+ +
+ + + + + + + + +

+ das heißt, in dem ins-Verb ist dann ein komplettes Objekt enthalten, +

+

+ nicht nur eine leere Record-Hülle, die nachfolgend populiert werden kann (aber nicht muß) +

+ +
+
+ + + + + + + + + + +

+ Konstruktor befüllt das Feld halt irgendwie. +

+

+ Ab dem Punkt verhält es sich aber wie ein normales (mandatory) Feld +

+ +
+
+ + + + + + +

+ das Objekt selber kann erkennen, ob das Feld sich im "default-Zustand" befindet +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +

+ ohne Prüfen ist emptySrc nicht implementierbar +

+ +
+ + + + + +

+ ...weil es für emptySrc keine neutrale Antwort gibt. +

+

+ Denn dieses Prädikat wird von der typischen Implementierung des Diff-Applikators +

+

+ in beiden Richtungen verwendet, also sowohl Prüfung auf empty ("expect no further elements"), +

+

+ alsauch der Check, daß überhaupt noch Quellelemente anstehen +

+ +
+
+ + + + + + +

+ d.h., man kann nur global auf Prüfung verzichten  +

+ +
+
+ + + + + + +

+ und da habe ich mich bereits dagegen entschieden +

+ +
+
+ + + + + + + + + + +

+ Feld unterstützt default-Wert +

+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + +

+ Auslegung der +

+

+ Primitiven +

+ +
+ + + + + + + + + + + + + + +

+ rationale: object fields are hard wired, +

+

+ thus always available +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ Einschränkung: accept_until END +

+ +
+ + + + + + +

+ ...nämlich indem alle Attribute als "berührt" und akzeptiert markiert werden. +

+

+ Somit könnten sofort Zuweisungen als Nächstes passieren +

+ +
+
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +

+ analog wie assignElm +

+ +
+
+ + + + + + + + + + + + + +

+ das heißt, es findet keine Verifikation statt +

+ +
+
+
+ + + + + + + + + + + + + + + +

+ zu bindende +

+

+ Operationen +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ sieht nach Ober-engineering aus, +

+

+ zumal das erhebliche Statefulness bewirkt +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

+ unterstelle Ziel als konstruierbar aus Payload +

+ +
+
+
+ + + + + + +

+ da effektiv bereits der Setter diese Funktionalität enthalten kann und muß, +

+

+ denn der Setter nimmt eine GenNode +

+ +
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ injectNew tolerieren +

+ +
+ + + + + + + +

+ ....man könnte genausogut auch beim ersten Mal zuweisen +

+ +
+
+ + + + + + +

+ denn die Diff-Anwendung auf GenNode unterstützt Zuweisung +

+

+ ausschließlich bei schon existierenden Elementen. Demnach muß dort auch jedes Attribut +

+
    +
  • + entweder schon mit dem Konstruktor mit gegeben worden sein +
  • +
  • + oder vorher einmal explizit eingefügt +
  • +
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ und die Keys der Attribute stecken in der GenNode selber! +

+ +
+
+
+ + + + + +
+
+ + + + + + + + + + + + + + + + + + +

+ ...denn wir vermeiden dadurch Komplexität. +

+

+ Der gesendete Diff muß einfach passen! +

+

+ Genau deshalb haben wir auch in GenNode verschiedene Varianten des gleichen Grundtyps, +

+

+ damit wir nicht in die ganzen Ungewissheiten der widening conversions laufen! +

+ +
+ +
+
+
+ + + + + + + + + + + + + + + + +

+ d.h. der Attributwert hat Wertsemantik und wird einfach zugewiesen +

+ +
+
+ + + + + + +

+ ...d.h. der Attributwert ist ein Objekt und damit ein nested Scope +

+ +
+
+ + + + + + + + + +

+ Problem: immutable values +

+ +
+ + + + + + + + + + + + + + + + + + + + + + +

+ das alles passiert dann im Lambda +

+ +
+
+ + +
+ + + + + + +

+ Dilemma: defaultable fields +

+ +
+ + + + + + + + + + + + +

+ ....mit der ETD, +

+

+ bzw der Anwendung des selben Diffs auf eine GenNode-Struktur. +

+

+ +

+

+ Konsequenz: wenn ein feld defaulted war, und nun explizit gesetzt wird, +

+

+ muß dies als INS geschehen, denn eine Zuweisung an nicht aufgeführtes Element ist verboten +

+ +
+
+ + + + + + + + + +

+ folglich ein Problem, +

+

+ zu erkennen, wenn wir fertig sind +

+ +
+
+ + + + + + + + + + + +

+ ....weil das defaultable field noch nicht vom Diff berührt wurde. +

+

+ Aber es ist kein optional field, d.h. wir haben keine Flag, die es als "defaulted" kennzeichnet +

+ +
+
+
+ + + + + + + + + + +

+ Lösung: alles immer explizit +

+ +
+ +
+
+ + + + + + + + + + + + + + + +

+ diese Lösung war zunächst mein Favorit. +

+

+ Sie erscheint sehr elegant, weil man im TreeMutator überhaupt nichts dafür tun muß. +

+

+ Und die Zusatz-Forderung, daß dann eben das Diff richtig gesendet werden muß, +

+

+ erscheint "geschenkt", da wir ohnehin zunächst einmal die Diffs explizit im Code erzeugen. +

+

+ +

+

+ Aber, nach längerer Überlegung wurde mir der Ansatz mehr und mehr zweifelhaft. +

+

+ Das ist die Art von Verkoppelungen, hier die implizite Annahme einer bestimmten Implementierung, +

+

+ die ein System unerklärbar und schwer wartbar machen. Das ist die Art von "Features", +

+

+ für die man sich nach einiger Zeit entschuldigen muß. +

+

+ +

+

+ Und noch schlimmer: eigentlich läuft dieser Ansatz darauf hinaus, die Konsistenzprüfung +

+

+ am Ende zu deaktivieren. Nur wir machen das nicht explizit, sondern durch die Hintertür. +

+

+ Also dann besser klar und ehrlich! +

+ +
+ +
+
+ + + + + + + + + +

+ ...denn unter dem Strich würden wir hiermit volle Unterstützung für opitonale Attribute einführen, +

+

+ also eine Attribut-Semantik auf eine Feld-Semantik draufpflanzen. +

+

+ Aber in der vorausgegangenen Analyse habe ich mich schon davon überzeugt, +

+

+ daß wir keine Attribut-Semantik brauchen. Und wenn doch, dann bietet das Diff-System +

+

+ immer noch die Möglichkeit, die Attribute explizit als Sammlung darzustellen. +

+ +
+ +
+
+ + + + + + +

+ auf die empty-Prüfung am Ende verzichten +

+ +
+ + +
+
+
+ + + + + + + + + +

+ denn in den meisten, wichtigsten Fällen get es um einen non-empty-check, +

+

+ bevor ein anderes Verifikations-Prädikat angewendet wird. +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ jedwede "bessere" Implementierung muß zwingend einen Container verwenden, +

+

+ der dann die Lambdas für die einzelnen Setter auf den Heap legt. +

+

+ Das ist hier tatsächlich viel schlechter, als das bischen lineare Suche +

+ +
+
+
+
+
+ + + + + + + + +

+ ....durch meinen allerersten Draft, +

+

+ für den ich damals gezwungen war, die GenNode zu erfinden :) +

+ +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ gleiches Argument... +

+ +
+
+ + + + + + +

+ ...damit unterstellen wir, daß später eine Symbol-Tabelle aufgebaut wird. +

+

+ Dann kann man sich immer noch überlegen, ob man dann an dieser Stelle bereinigt +

+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ in einem Fall kann man sie aus der Closure abgreifen +

+

+ im anderen Fall muß es doch der Client leisten. +

+

+ Keine klare Linie +

+ +
+ +
+ + + + + + + + + + +

+ ...das heißt, es gibt nur minimale, themantische Überlappung. +

+

+ Also ist die Verwendung von Vererbung hier sogar die beste Lösung +

+ +
+ +
+ + + + + + +

+ Geschachtelte Typdefs lassen sich vermeiden: +

+

+ BareEntryID speichern! +

+ +
+ +
+ + + + + + +

+ ...das heißt, wie rum man es auch auflöst, wird die Lösung auf einer Seite schlechter +

+
    +
  • + wenn wir für den Payload-Typ einen Typ-Parameter nehmen, blähen wir den Standard-Fall (Setter) auf +
  • +
  • + andererseits ist es unbstreitbar einfach so, daß für den Mutator-Builder die Typisierung komplett implizit ist, das muß die Closure mit sich selbst ausmachen, einfach indem in der Closure ein geschachtelter TreeMutator konstruiert wird, der eben mit diesem impliziten Kind-Typ umgehen kann. +
  • +
  • + wenn wir stattdessen nur einen Key-String speichern, wird zum Einen die Match-Prüfung aufwendiger (Stringvergleich statt Vergleich von Hashes), und außerdem wird ein Typ-Mismatch nicht mehr auf der Ebene der Verb-Anwendung entdeckt und entsprechend gekennzeichnet, sondern wir hoffen, daß es dann innerhalb der Closure zu einem Fehlzugriff auf die Payload der GenNode kommt. Noch schlimmer im Mutator-Fall, da sind wir dann schon im geschachtelten Scope und hoffen, daß dann der eingeschachtelte Mutator irgendwo auf Widerspruch läuft. +
  • +
+ +
+ +
+ + + + + + +

+ ...gedacht für verschiedene UseCases. +

+
    +
  • + Fall 1: String-Key und der Typ muß irgendwie implizit/explizit gegeben sein +
  • +
  • + Fall2: GenNodeID +
  • +
+ +
+ +
+ + + + + + +

+ ...die offensichtlichsten Dinge übersieht man nur zu leicht!!!!! +

+

+ Da es ein nested scope ist, ist es immer ein Objekt, +

+

+ also repräsentiert als Rec<GenNode> +

+ +
+ +
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ zwei Bindings +

+ +
+ + + + + + +
+ + + + + + + + + + + + + +

+ zwei Collection-Bindings +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ ...diese Abkürzung ist nur auf den Konstruktur aufgepflanzt, +

+

+ nicht aber in der eigentlichen Implementierung verankert. +

+

+ Das wollte ich nicht, weil ich längerfristig doch davon ausgehe, +

+

+ daß es einfach einen Metadaten-Scope gibt +

+

+ +

+

+ Die Inkonsequenz nun ist, daß im Rec::Mutator keine Magie dafür vorgesehen ist +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

+ ...mit den Lambdas kann ich nur die Sicht auf die Werte steuern, +

+

+ nicht aber das eigentliche Verhalten des Bindings. +

+

+ +

+

+ Denn die Lambdas haben keinen Zugriff auf die Ziel-Datenstruktur! +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

+ ...wir wollen mehrfach geschichtete TreeMutator-Subklassen, +

+

+ aber tatsächlich liefert jeder DSL-Aufruf einen Builder<TreeMutator<...>>. +

+

+ Die normalen DSL-Aufrufe sind eben genau so gestrickt, daß jeweils der oberste Builder entfernt wird, +

+

+ ein neuer Layer darübergebaut und das Ganze wieder in einen Builder eingewickelt wird. +

+

+ +

+

+ Dadurch ist es schwer bis unmöglich (wg. den Lambdas), den resultierenden Typ anzuschreiben. +

+

+ Daher bin ich zwingend auf Wrapper-Funktionen angewiesen, die diesen resultierenden Typ +

+

+ vom konkreten Aufruf wieder "abgreifen". Ich kann daher nicht die DSL-Notation verwenden, +

+

+ um den Dekorator für die Behandlung des Typ-Feldes einzubringen. +

+ +
+
+
+
+
+
+ + + + + + + + + + +

+ Mut -> Rekursion +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ Problem: partielle Ordnung +

+ +
+ + + + + + + + + + + + + +

+ ...das heißt, +

+

+ das AFTER-Verb wird übersetzt in ein skip_until, +

+

+ und das läuft dann entweder in jedem Layer +

+

+ oder nur in dem Layer, der auf die Spec paßt. +

+

+ In jedem Fall gerät dadurch die relative Verzahnung der Elemente untereinander aus dem Takt +

+ +
+
+ + + + + + + +

+ ...das heißt also, es wird stets der zuerst gebundene Layer komplett durchgespult, +

+

+ gefolgt dann von dem nächsten Layer. +

+

+ +

+

+ Die Konsequenz ist, daß es keine Mischung der Typen geben kann. +

+

+ Es müssen immer zwingend alle Elemente eines Typs von einem Layer behandelt werden +

+

+ und diese Elemente müssen geschlossen hintereinander in der Reihenfolge liegen +

+ +
+
+
+
+
+
+ + + + + + + + +

+ auf Basis des neu geschaffenen TreeMutators +

+ +
+ + + + + + + + + + + +

+ ....man könnte später geeignete Automatismen schaffen, +

+

+ die sich diesen TreeMutator beschaffen +

+
    +
  • + indem erkannt wird, daß das eigentliche Zielobjekt ein bestimmtes API bietet +
  • +
  • + indem andere relevante Eigenschaften des Zielobjekts erkannt werden +
  • +
+ +
+ + +
+ + + + + + +

+ ...das so häufig in C++ auftretende Problem: +

+

+ wie baue und verwalte ich eine konkrete Implementierung, +

+

+ ohne gleich ein ganzes Management-Framework einführen zu müssen. +

+

+ Letzten Endes lief  das auch in diesem Fall auf inline-Storage hinaus... +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ ....daß ein unbedarfter client diesen Trick übershieht +

+

+ und daher den Rückgabewert wegwirft. +

+

+ +

+

+ Argument: we soweit einsteigt, die Metaprogramming-Lösung zu nutzen, +

+

+ sollte auch intelligent genug sein, die API-Doc zu lesen. +

+

+ +

+

+ Standard == Interface DiffMutable implementieren +

+ +
+ +
+
+ + + + + + + + + + + +

+ Client soll direkt mutatorBinding bieten +

+ +
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + +

+ nicht generisch: mutatorBinding +

+ +
+ +
+
+ + + + + + +

+ Lösungsversuch: extern template +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ ...im Klartext: diesen Zugriff von der generischen Implementierung +

+

+ auf den eingebauten Stack-Mechanismus benötigen wir nur... +

+
    +
  • + einmal zu Beginn, bei der Konstruktion +
  • +
  • + wenn wir in einen geschachtelten Scope eintreten +
  • +
  • + wenn wir einen Solchen verlassen +
  • +
+

+ Zwar sind indirekte Calls aufwendiger, aber letzten Endes auch wieder nicht soooo aufwendig, +

+

+ daß sie uns im gegebenen Kontext umbringen... +

+ +
+ +
+
+ + + + + + + + + + + + +

+ intern: eingebaute initDiffApplication() +

+ +
+ + + + + +

+ ...wird automatisch vor Konsumieren eines Diff aufgerufen +

+ +
+
+ + + + + + +

+ Widerspruch: TreeMutator ist Wegwerf-Objekt +

+ +
+ +
+ + + + +
+
+ + + + + + +

+ Lösungsversuch: doppelte Hülle +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ kann daher TreeMutator konstruieren +

+ +
+
+ + + + + + +

+ ...und zwar per mutatorBinding +

+ +
+
+ + + + + + +

+ implementiert somit initDiffApplication() +

+ +
+
+
+
+ + + + + + +

+ TODO: Namensgebung +

+ +
+ + + + + + + + + + +
+
+ + + + + + + + + + + +

+ TreeMutator-Binding muß opaque bleiben +

+ +
+
+ + + + + + +

+ Buffer-Größen-Management vorsehen +

+ +
+ + + + + + + + +

+ das heißt +

+
    +
  • + ein sinnvoller Startwert wird heuristisch vorgegeben +
  • +
  • + wenn die Allokation scheitert, die Exception fangen und die tatsächlich benötigte Größe merken +
  • +
+ +
+
+ + + + + + + + + + + + + + + +

+ ...das heißt: +

+

+ gegeben ein syntaktisch sinnvoller top-level-Aufruf ("wende das Diff an") +

+

+ -- wie bzw. von wem bekommen wir dann ein Binding, das einen passenden TreeMutator konstruiert? +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ erscheint mir die am wenigsten überraschende Lösung. +

+

+ und zwar per handle.get() +

+ +
+ +
+ + + + + + + +

+ erscheint mir fehleranfällig und irreführend für den Nutzer der Schnittstelle. +

+

+ Denn er muß zwar das Objekt in das Handle platzieren, dann aber auch noch einen Pointer zurückgeben, +

+

+ der dann auch noch NULL sein kann, zum Signalisieren von Fehlern. +

+

+ Ich empfinde das als schlechten Stil +

+ +
+ +
+ + + + + + +

+ naja, das wäre billig, aber auch wieder beliebig. +

+

+ Es macht keinen Sinn vom API-Design her, sondern man müßte es halt machen, +

+

+ weil die Implementierung den Zeiger auf den geschachtelen sub-Mutator umsetzen muß. +

+ +
+ +
+
+
+ + + + + + + + + + + + +

+ die Diff-Sprache verlangt, +

+

+ daß vor dem Öffnen des geschachtelten Scopes +

+

+ dieser zumindest einmal per ins "angelegt" wurde. +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+ ...das ist ein Versuch, den Code für den Leser verständlich zu halten. +

+

+ Die Idee ist, daß es einen high-level Unit-Test gibt, der die gesamte Diff-Anwendung durchspielt +

+

+ und dazu passend einen low-level Unit-Test, der analog die gleichen Operationen macht, +

+

+ allerdings direkt auf dem TreeDiff-Interface durch Aufruf der passenden Primitiv-Operaionen. +

+

+ Letztere müssen für jede Art von "onion-layer" (konkretes Binding) erneut implementiert +

+

+ und daher auch jeweils eigens per Unit-Test abgedeckt werden. +

+ +
+
+ + + + + + +

+ das ist hier sinnvoll. Das Binding sollte komplexer sein, +

+

+ als in der Praxis auftretende Bindings. Warum? Weil letztere immer etwas einseitg sind +

+

+ und damit Abkürzungen im Code-Pfad ausnützen. Die Gefahr schlummert aber im Zusammenspiel +

+

+ der konkreten Bindings mit mehreren "onion layers"! +

+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + +

+ ...denn es ist sehr verwirrend, welche Signatur denn nun die Lambdas haben müssen +

+ +
+ + +
+ + + + + + +

+ ...denn es kann keinen Default-Matcher geben.... +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + +

+ ...sonst wird niemand Lambdas bereitstellen können, oder gar Diff-Nachrichten erzeugen. +

+

+ Das ist nun kein spezielles Problem der gewählten Implementierungs-Technik, sondern rührt daher, +

+

+ daß der Client hier eigentlich ein Protokoll implementieren muß. +

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ wenn überhaupt, dann im Matcher im Binding-Layer implementieren +

+ +
+ +
+ + + + + + +

+ ...denn wir haben nun mehrere Layer, +

+

+ und der Selector kann einfach anhand von Ref::THIS keine sinnvolle Entscheidung treffen. +

+

+ Daher versuchen dann alle Layer dieses Element zu behandeln, oder gar keiner +

+

+ +

+

+ Und da der Selector nur die Spec anschauen darf, läßt sich das auch nachher nicht mehr korrigieren +

+

+ +

+

+ Daher habe ich mich entschlossen, dieses Sprachkonstrukt zu entfernen +

+ +
+
+ + + + + + +

+ entfernt, da schlechtes Design +

+ +
+
+
+ + + + + + + + + + + +

+ entfernt, da schlechtes Design +

+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + +

+ anscheinend nicht notwendig +

+ +
+ +
+ + + + + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -40550,9 +41147,9 @@ - + - + @@ -40584,7 +41181,7 @@ - + @@ -40674,7 +41271,7 @@ - + @@ -40759,7 +41356,7 @@ - + @@ -40769,10 +41366,11 @@ das heißt: nicht einmal abhängig von der STL

-
+ +
- + @@ -40782,12 +41380,13 @@ wie gson

-
+ +
- + @@ -40800,8 +41399,9 @@ nach dem Umzug auf Github heißt es gason

-
- + + + @@ -40811,11 +41411,12 @@ lt. eigenen Benchmakrs deutlich schneller als rapidjson, welches eigentlich immer als der "schnelle" JSON-Parser gilt.

-
+ +
- + @@ -40825,7 +41426,8 @@ d.h. das Parsen schreibt den Eingabepuffer um, und Strings bleiben einfach liegen

-
+ +
@@ -40838,7 +41440,7 @@ - + @@ -40848,7 +41450,8 @@ kein Repo auffindbar

-
+ +
@@ -40908,7 +41511,7 @@ - + @@ -40932,7 +41535,8 @@ - + + @@ -40941,7 +41545,7 @@ - + @@ -40951,7 +41555,8 @@ habe einen usleep(1000) getimed

-
+ +
@@ -40962,7 +41567,7 @@
- + @@ -40984,7 +41589,8 @@ Außerdem ist ja auch noch der Aufruf des Funktors mit im Spiel, wenngleich der auch typischerweise geinlined wird

-
+ + @@ -41011,7 +41617,7 @@ - + @@ -41024,7 +41630,8 @@ daß x86_64 tatsächlich cache-kohärent ist

-
+ +
@@ -41069,7 +41676,7 @@
- + @@ -41090,7 +41697,8 @@ - + + @@ -43446,7 +44054,7 @@ - + @@ -43459,7 +44067,8 @@ Visitor ist entweder void, oder bool

-
+ +
@@ -43485,7 +44094,7 @@
- + @@ -43500,7 +44109,8 @@ - + + @@ -43509,7 +44119,7 @@ - + @@ -43530,7 +44140,8 @@ - + + @@ -43625,7 +44236,7 @@ - + @@ -43656,7 +44267,8 @@ Denn letzteres ist bei uns eine Grundannahme. Es gibt keine ungefähren Diffs!

-
+ +
@@ -46421,7 +47033,7 @@ - + @@ -46439,7 +47051,8 @@ - + + @@ -46815,7 +47428,7 @@ - + @@ -46831,14 +47444,15 @@ Ganz prominent fehlt hier also z.B: MIDI

-
+ +
- + @@ -46851,7 +47465,8 @@ die Aufgrund von Klassifikationen automatisch bereits existieren

-
+ +
@@ -46873,7 +47488,7 @@ - + @@ -46883,7 +47498,8 @@ Meta-Assets sind per Definition "immutable"
Es gibt einen Builder

-
+ + @@ -46903,7 +47519,7 @@ - + @@ -46919,7 +47535,8 @@ über den UI-Bus schickt, an einen Empfänger mit bekannter ID.

-
+ +
@@ -46937,7 +47554,7 @@
- + @@ -46948,7 +47565,7 @@

- +
@@ -46962,7 +47579,7 @@ - + @@ -46975,10 +47592,11 @@ dadurch werden Meta-Operationen auf gleiche Ebene gestellt wie normale Struktur-Manipulationen

-
+ +
- + @@ -47005,7 +47623,8 @@ und verlieren ihren magischen Charakter außerhalb der Event-Sourcing-Struktur

-
+ +
@@ -47033,7 +47652,7 @@
- + @@ -47126,7 +47745,7 @@ - + @@ -47139,11 +47758,12 @@ we need to wait for the current command or builder run to be completed

-
+ +
- + @@ -47153,7 +47773,8 @@ ...noch nicht implementiert 1/17

-
+ + @@ -47172,7 +47793,7 @@ - + @@ -47182,7 +47803,8 @@ Guard beim Zugang über das Interface

-
+ +
@@ -47262,7 +47884,7 @@ - + @@ -47301,7 +47923,8 @@ OO rocks!

-
+ +
@@ -47368,7 +47991,7 @@
- + @@ -47386,7 +48009,8 @@ - + +
@@ -47672,7 +48296,7 @@ - + @@ -47685,7 +48309,8 @@ insofern Container auf das DESTROY-Signal ihrer Kinder reagieren

-
+ +
@@ -47737,7 +48362,7 @@ - + @@ -47747,7 +48372,8 @@ ...also abzüglich Dekoration und Margin

-
+ +
@@ -47756,7 +48382,7 @@ - + @@ -47769,7 +48395,8 @@ sofern das Widget mit entsprechendem Modus eingefügt wurde

-
+ +
@@ -47792,7 +48419,7 @@ - + @@ -47802,7 +48429,8 @@ "Widget is in a background toplevel window"

-
+ +
@@ -47825,7 +48453,7 @@
- + @@ -47850,11 +48478,12 @@ indem man eine eigene XXX_class_init() - Funktion schreibt

-
+ +
- + @@ -47864,12 +48493,13 @@ in den Fällen, die ich mir angeschaut habe, steht dieser String hart codiert in der XXXX_class_init()-Funktion

-
+ +
- + @@ -47879,9 +48509,10 @@ d.h. die angegebenen Abmessungen entsprechen der bounding box

-
+ +
- + @@ -47903,7 +48534,8 @@ in diesem Falle würde die linke Border mit der geerben Farbe gezeichnet, und nicht gelb

-
+ +
@@ -47912,7 +48544,7 @@ - + @@ -47922,7 +48554,8 @@ <offX> <offY> [<blur> [<spread>]] <colour>

-
+ +
@@ -47945,7 +48578,7 @@ - + @@ -47955,7 +48588,8 @@ d.h. wir haben Referenz-Semantik

-
+ +
@@ -47967,7 +48601,7 @@ - + @@ -47983,9 +48617,10 @@ automatisch eine höhere Priorität haben, als das, was sich aus den Path-match ergibt

-
+ +
- + @@ -48013,7 +48648,8 @@ Man muß also genügend Platz allozieren für border-top-width + border-bottom-width + gewünschter Content!

-
+ +
@@ -48029,7 +48665,7 @@ - + @@ -48042,7 +48678,8 @@ context->add_class("ohMy");

-
+ + @@ -48078,7 +48715,7 @@
- + @@ -48088,9 +48725,10 @@ this->set_name("my-widget")

-
+ + - + @@ -48145,10 +48783,11 @@   // changed or removed in the future.

-
+ + - + @@ -48158,7 +48797,8 @@ gtk_widget_class_set_css_name (GTK_WIDGET_GET_CLASS(gobj()), "body");

-
+ +
@@ -48198,7 +48838,7 @@ - + @@ -48214,7 +48854,8 @@ oder ist es eine Vererbungs-Hierarchie, wie sie für das CSS-Styling benötigt wird?

-
+ +
@@ -48228,7 +48869,7 @@ - + @@ -48292,7 +48933,8 @@ apply styles to that specific widget their gtkrc file.

-
+ +
@@ -48308,7 +48950,7 @@
- + @@ -48321,7 +48963,8 @@ mit automatischem Refcounting

-
+ +
@@ -48329,7 +48972,7 @@ - + @@ -48339,7 +48982,8 @@ As a consequence, the style will be regenerated to match the new given path.

-
+ +
@@ -48390,7 +49034,7 @@ - + @@ -48414,7 +49058,8 @@ - + + @@ -48873,7 +49518,7 @@ - + @@ -48886,9 +49531,10 @@ aber macht in etwa die gleichen Operationen

-
+ +
- + @@ -48907,7 +49553,8 @@ Gtk-Main verwendet inzwischen den gleichen Mechanismus

-
+ +
@@ -48920,7 +49567,7 @@ - + @@ -48942,7 +49589,8 @@ Das ist eine subtile Falle.

-
+ +
@@ -48961,7 +49609,7 @@ - + @@ -48984,7 +49632,8 @@ alles das nicht aus dem GUI-Thread heraus geschieht

-
+ +
@@ -49040,7 +49689,7 @@ - + @@ -49050,9 +49699,10 @@ ...ob beim Expand/Collapse das umschließende Widget resized werden soll

-
+ +
- + @@ -49062,12 +49712,13 @@ ob eingeklappt oder ausgeklappt

-
+ +
- + @@ -49080,7 +49731,8 @@ was dazu führt, daß das Kind stets allen verfügbaren Platz nimmt

-
+ +
@@ -49184,7 +49836,7 @@
- + @@ -49194,7 +49846,8 @@ This function is only used by Gtk::Container subclasses, to assign a size, position and (optionally) baseline to their child widgets.

-
+ +
@@ -49223,7 +49876,7 @@
- + @@ -49236,7 +49889,8 @@   _release_c_instance();

-
+ +
@@ -49279,7 +49933,7 @@
- + @@ -49292,7 +49946,8 @@ wenn das managende Widget zerstört wird

-
+ +
@@ -49314,7 +49969,7 @@ - + @@ -49327,7 +49982,8 @@ ggfs. neu gemapped und invalidiert wird, woraufhin es neu gezeichnet wird

-
+ +
@@ -49359,7 +50015,7 @@ - + @@ -49372,7 +50028,8 @@ Siehe Beschreibung im Beispiel/Tutorial

-
+ +
@@ -49381,7 +50038,7 @@
- + @@ -49394,7 +50051,8 @@ Im Besonderen kann man sich an Signale anderer Widgets anhängen

-
+ + @@ -49776,7 +50434,7 @@ - + @@ -49792,7 +50450,8 @@ und auch ein Signal für Parse-Fehler anschließt

-
+ +
@@ -49819,7 +50478,7 @@ - + @@ -49837,7 +50496,8 @@ Beachte: der Text-Cursor (Marker "insert") hat right gravity

-
+ +
@@ -49912,7 +50572,7 @@ - + @@ -49934,7 +50594,8 @@ The grip is implemented as a GdlDockItemGrip

-
+ +
@@ -50015,7 +50676,7 @@

- + @@ -50025,9 +50686,10 @@ kann eines der Templates im Zyklus vorrübergehend als "incomplete" gelten.

-
+ +
- + @@ -50049,7 +50711,8 @@ Konsequenz: man wählt dann z.B. eine subtil falsche Spezialisierung.

-
+ +
@@ -50075,7 +50738,7 @@ - + @@ -50103,13 +50766,14 @@ selber aus einem statischen Initialisierungs-Kontext heraus erfolgt.

-
+ +
- + @@ -50305,7 +50969,8 @@   }

-
+ +
@@ -50324,7 +50989,7 @@ - + @@ -50334,7 +50999,8 @@ das sind verschiedene Blickwinkel auf das gleiche Thema

-
+ + @@ -50343,7 +51009,7 @@ - + @@ -50361,7 +51027,8 @@ - + + @@ -50445,7 +51112,7 @@ - + @@ -50476,7 +51143,8 @@ Allerdinsg nicht auf einer Plattform, die ohnehin sequentiell-konsistent ist. Wie "zum Beispiel" x86/64

-
+ +
@@ -50524,7 +51192,7 @@
- + @@ -50537,7 +51205,8 @@ die shared zone anzufassen!

-
+ +
@@ -50547,7 +51216,7 @@ - + @@ -50572,9 +51241,10 @@ Query<RES>::resolveBy

-
+ +
- + @@ -50609,14 +51279,15 @@ sonst kommt Doxygen durcheinander

-
+ +
- + @@ -50638,7 +51309,8 @@ wird hier kein Link erzeugt

-
+ +
@@ -50654,7 +51326,7 @@ - + @@ -50670,7 +51342,8 @@ Die Icon-Größen ergeben sich aus den Boxes auf 'plate'

-
+ +
@@ -50685,7 +51358,7 @@ - + @@ -50695,7 +51368,8 @@ ...im Besonderen die guten Diagramme für Pulse, ALSA und Jack

-
+ +
@@ -50852,7 +51526,7 @@
- + @@ -50875,10 +51549,11 @@ "-Wl,-rpath-link=target/modules"

-
+ +
- + @@ -50888,14 +51563,15 @@ laufen wieder alle

-
+ + - + @@ -50905,7 +51581,8 @@ test.sh Zeile 138

-
+ +
@@ -50949,7 +51626,7 @@ - + @@ -50959,12 +51636,13 @@ und wir verbringen unsere Zeit mit contention

-
+ +
- + @@ -50974,7 +51652,8 @@ ist klar, hab ich gebrochen

-
+ + @@ -50990,7 +51669,7 @@ - + @@ -51003,7 +51682,8 @@ Vorher hatte ich erste Kollisionen nach 25000 Nummern

-
+ +
@@ -51042,7 +51722,7 @@
- + @@ -51055,7 +51735,8 @@ Aug 10 04:51:39 flaucher kernel: traps: test-suite[8249] trap int3 ip:7ffff7deb241 sp:7fffffffe5c8 error:0

-
+ + @@ -51112,7 +51793,7 @@ - + @@ -51122,7 +51803,8 @@ bison dejagnu flex gobjc libncurses5-dev libreadline-dev liblzma-dev libbabeltrace-dev libbabeltrace-ctf-dev python3-dev

-
+ +
@@ -51138,7 +51820,7 @@ - + @@ -51172,7 +51854,8 @@ au weia LEUTE!

-
+ +
@@ -51196,7 +51879,7 @@
- + @@ -51212,10 +51895,11 @@ und tatsächlich: das ist daneben, GCC hat Recht!

-
+ +
- + @@ -51225,7 +51909,8 @@ aktualisieren und neu bauen

-
+ +
@@ -51245,7 +51930,7 @@ - + @@ -51255,7 +51940,8 @@ wähle Kompatibiltät genau so, daß Ubuntu-Trusty noch unterstützt wird.

-
+ + @@ -51296,7 +51982,7 @@ - + @@ -51306,14 +51992,15 @@ env.GuiResource(f) for f in env.Glob('stage/*.css')

-
+ +
- + @@ -51323,9 +52010,10 @@ wenn ich doch mal noch komplexere Bäume transportieren muß

-
+ +
- + @@ -51335,7 +52023,8 @@ ich mag code-nahe Resourcen lieber beim Code selber

-
+ +
@@ -51344,7 +52033,7 @@ - + @@ -51365,11 +52054,12 @@ - + + - + @@ -51385,7 +52075,8 @@ Dann

-
+ +
@@ -51393,7 +52084,7 @@ - + @@ -51403,7 +52094,8 @@ nämlich im src/SConscript, wenn es um das GUI geht

-
+ +
@@ -51435,7 +52127,7 @@ - + @@ -51448,9 +52140,10 @@ Ich meine also: zu Beginn vom Build sollte das Buildsystem einmal eine Infozeile ausgeben

-
+ +
- + @@ -51460,7 +52153,8 @@ ...denn die stören jeweils beim erzeugen eines Hotfix/Patch im Paketbau per dpkg --commit

-
+ +
@@ -51507,7 +52201,7 @@
- + @@ -51517,11 +52211,12 @@ Doku durchkämmen nach Müll

-
+ + - + @@ -51534,10 +52229,11 @@ WICHTIG: keine vorgreifende Infor publizieren!!!!!

-
+ +
- + @@ -51553,7 +52249,8 @@ insgesamt sorgfältig durchlesen

-
+ + @@ -51563,7 +52260,7 @@ - + @@ -51573,7 +52270,8 @@ knappe Kennzeichnung des Releases in den Kommentar

-
+ + @@ -51581,7 +52279,7 @@ - + @@ -51600,7 +52298,8 @@ denn wir wollen keine DEB-Info im Master haben!

-
+ + @@ -51613,7 +52312,7 @@
- + @@ -51626,7 +52325,8 @@ die unmittelbaren Release-Dokumente durchgehen

-
+ + @@ -51640,7 +52340,7 @@ - + @@ -51653,7 +52353,8 @@ Sollte konfliktfrei sein

-
+ +
@@ -51676,7 +52377,7 @@
- + @@ -51686,7 +52387,8 @@ ...das heißt bauen und hochladen

-
+ + @@ -51740,7 +52442,7 @@ - + @@ -51753,9 +52455,10 @@ unter Debian/Jessie wird das ignoriert

-
+ +
- + @@ -51781,7 +52484,8 @@ Die Wahrscheinlichkeit, daß irgend jemand Lumiera unter Ubuntu/Trusty installieren möchte, erscheint mir akademisch

-
+ +
@@ -51807,7 +52511,7 @@ - + @@ -51817,7 +52521,8 @@ in lib/hash-standard.hpp

-
+ +
@@ -51832,7 +52537,7 @@ - + @@ -51852,7 +52557,8 @@ es gibt Probleme beim Linken mit den Boost-Libraries, die auf Ubuntu/wily mit gcc-5 gebaut sind.

-
+ +
@@ -51860,7 +52566,7 @@ - + @@ -51870,7 +52576,8 @@ Wichtig: hier nur was wirklich gebaut ist und funktioniert!

-
+ +
@@ -51894,7 +52601,7 @@ - + @@ -51910,7 +52617,8 @@ bestehen, aber irgendwann müssen wir das schon glattziehen

-
+ +
@@ -51948,7 +52656,7 @@ - + @@ -51958,7 +52666,8 @@ seit gcc-4.8 ist kein static_assert mehr in der STDlib

-
+ +
@@ -52047,7 +52756,7 @@ - + @@ -52063,7 +52772,8 @@ !!!!!11!!

-
+ +
@@ -52093,7 +52803,7 @@ - + @@ -52139,10 +52849,11 @@ END

-
+ + - + @@ -52152,11 +52863,12 @@ for I in `seq 1 50`; do target/test-suite CallQueue_test; done

-
+ +
- + @@ -52172,7 +52884,8 @@ und eine Doxygen-Seite im Browser geladen

-
+ +
@@ -52193,7 +52906,7 @@ - + @@ -52203,7 +52916,8 @@ weil sich die Threads gegenseitig ihre Counter inkrementieren.

-
+ +
@@ -52215,7 +52929,7 @@ - + @@ -52228,7 +52942,8 @@ verwenden globale Variable oder überhaupt keine Objektfelder

-
+ +
@@ -52285,7 +53000,7 @@ - + @@ -52301,7 +53016,8 @@ und dann auf den Deaktiviert-Zustand wartet

-
+ +
@@ -52309,7 +53025,7 @@ - + @@ -52322,7 +53038,8 @@ nachdem einmal ein wait mit Timeout verwendet worden war

-
+ +
@@ -52362,7 +53079,7 @@
- + @@ -52375,7 +53092,8 @@ obwohl noch der Builder läuft

-
+ +