From 8e990fc04d424a3975f82f1c5d30ba80580da998 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 3 Jul 2015 19:18:49 +0200 Subject: [PATCH] WIP: simple implementation / stubbing especially I've now decided how to handle const-ness: We're open to all forms of const-ness, the actual usage decides. const GenNode will only expose a const& to the data values still TODO is the object builder notation for diff::Record --- src/lib/diff/gen-node.hpp | 8 +- src/lib/variant.hpp | 6 + tests/library/diff/gen-node-basic-test.cpp | 2 + .../diff/generic-tree-mutator-test.cpp | 14 --- wiki/renderengine.html | 14 ++- wiki/thinkPad.ichthyo.mm | 116 ++++++++++++++++-- 6 files changed, 131 insertions(+), 29 deletions(-) diff --git a/src/lib/diff/gen-node.hpp b/src/lib/diff/gen-node.hpp index 947fcfc4b..594f0881d 100644 --- a/src/lib/diff/gen-node.hpp +++ b/src/lib/diff/gen-node.hpp @@ -104,8 +104,7 @@ #include "lib/idi/entry-id.hpp" //#include "lib/util.hpp" //#include "lib/format-string.hpp" - -#include "lib/format-util.hpp" +//#include "lib/format-util.hpp" #include "lib/variant.hpp" #include "lib/util.hpp" @@ -182,6 +181,11 @@ namespace diff{ { } // standard copy operations acceptable + + operator string() const + { + return "ID(\""+getSym()+"\")"; + } }; diff --git a/src/lib/variant.hpp b/src/lib/variant.hpp index 6a6640e7b..35a9d40e0 100644 --- a/src/lib/variant.hpp +++ b/src/lib/variant.hpp @@ -404,6 +404,12 @@ namespace lib { return buff().access(); } + template + X const& + get() const + { + return unConst(this)->get(); + } void accept (Visitor& visitor) diff --git a/tests/library/diff/gen-node-basic-test.cpp b/tests/library/diff/gen-node-basic-test.cpp index 161b47854..cd561579b 100644 --- a/tests/library/diff/gen-node-basic-test.cpp +++ b/tests/library/diff/gen-node-basic-test.cpp @@ -36,6 +36,8 @@ using util::isnil; using util::contains; using util::isSameObject; +using lib::hash::LuidH; +using lib::time::FSecs; using lib::time::Time; using lib::time::TimeSpan; //using std::string; diff --git a/tests/library/diff/generic-tree-mutator-test.cpp b/tests/library/diff/generic-tree-mutator-test.cpp index e06406196..f6b10803e 100644 --- a/tests/library/diff/generic-tree-mutator-test.cpp +++ b/tests/library/diff/generic-tree-mutator-test.cpp @@ -79,9 +79,7 @@ namespace test{ run (Arg) { simpleAttributeBinding(); - verifySnapshot(); sequenceIteration(); - duplicateDetection(); copy_and_move(); } @@ -113,24 +111,12 @@ namespace test{ } - void - verifySnapshot() - { - } - - void sequenceIteration() { } - void - duplicateDetection() - { - } - - void copy_and_move() { diff --git a/wiki/renderengine.html b/wiki/renderengine.html index a99b9c12f..c9d87bc26 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -2316,13 +2316,17 @@ For this Lumiera design, we could consider making GOP just another raw media dat →see in [[Wikipedia|http://en.wikipedia.org/wiki/Group_of_pictures]] -
+
//Abstract generic node element to build a ~DOM-like rendering of Lumiera's [[session model|HighLevelModel]].//
 GenNode elements are values, yet behave polymorphic. They are rather light-weight, have an well established identity and can be compared. They are //generic// insofar they encompass several heterogeneous ordering systems, which in themselves can not be subsumed into a single ordering hierarchy. The //purpose// of these generic nodes is to build a symbolic representation, known as [[external tree description|ExternalTreeDescription]], existing somewhere "outside", at a level where the fine points of ordering system relations do not really matter. Largely, this external description is not represented or layed down as a whole. Rather, it is used as a conceptual reference frame to describe //differences and changes.// Obviously, this means that parts of the altered structures have to appear in the description of the modifications. So, practically speaking, the prime purpose of GenNode elements is to appear as bits of information within a ''diff language'' to exchange such information of changes.
 
 To be more specific, within the actual model there are [[Placements|Placement]]. These refer to [[M-Objects|MObject]]. Which in turn rely on [[Assets|Asset]]. Moreover, we have some processing rules, and -- last but not least -- the "objects" encountered in the model have state, visible as attributes of atomic value type (integral, floating point, string, boolean, time, time ranges and [[quantised time entities|TimeQuant]]).
 A generic node may //represent any of these kind// -- and it may have ~GenNode children, forming a tree. Effectively all of this together makes ~GenNode a ''Monad''.
 
+GenNode elements are conceived as values, and can thus be treated as mutable or immutable; it is up to the user to express this intent through const correctness.
+Especially the nested structures, i.e. a GenNode holding an embedded {{{diff::Record}}}, are by default immutable, but expose a object builder API for remoulding. This again places the actual decision about mutations into the usage context, since the remoulded Record has to be assigned explicitly.
+
+
 !to reflect or not reflect
 When dealing with this external model representation, indeed there are some rather global concerns which lend themselves to a generic programming style. Simply because, otherwise, we'd end up explicating and thereby duplicating the structure of the model all over the code. Frequently, such a situation is quoted as the reason to demand introspection facilities on any data structure. We doubt this is a valid conclusion. Since introspection allows to accept just //any element// -- followed by an open-ended //reaction on the received type// -- we might arrive at the impression that our code reaches a maximum of flexibility and "openness". Unfortunately, this turns out to be a self-deception, since code to do any meaningful operation needs pre-established knowledge about the meaning of the data to be processed. More so, when, as in any hierarchical data organisation, the relevant meaning is attached to the structure itself, so consequently this pre-established knowledge tends to be scattered over several, superficially "open" handler functions. What looks open and flexible at first sight is in fact littered with obscure and scattered, non obvious additional presumptions.
 This observation from coding practice gets us to the conclusion, that we do not really want to support the full notion of data and type introspection. We //do want// some kind of passive matching on structure, where the receiver explicitly has to supply structural presuppositions. In a fully functional language with a correspondingly rich type system, a partial function (pattern match) would be the solution of choice. Under the given circumstances, we're able to emulate this pattern based on our variant visitor -- which basically calls a different virtual function for each of the types possibly to be encountered "within" a ~GenNode.
@@ -7943,7 +7947,7 @@ Used this way, diff representation helps to separate structure and raw data in e :Chunks of raw data are attached inline to the structural diff, assuming that each element implicitly knows the kind of data to expect
-
+
//This page details decisions taken for implementation of Lumiera's diff handling framework//
 This topic is rather abstract, since diff handling is multi purpose within Lumiera: Diff representation is seen as a meta language and abstraction mechanism; it enables tight collaboration without the need to tie and tangle the involved implementation data structures. Used this way, diff representation reduces coupling and helps to cut down overall complexity -- so to justify the considerable amount of complexity seen within the diff framework implementation.
 
@@ -7999,13 +8003,15 @@ It should be noted, that the purpose of this whole architecture is to deal with
 {{red{open questions 6/15}}}
 * do we need to //alter// object contents -- or do we just replace?
 * to what degree is the distinction between attributes and children even relevant -- beyond the ability to address attributes by-name?
-* how do we describe an object from scratch?
+* how do we describe an object from scratch? ←''object builder''
 * how do we represent the break between attributes and children in this linearised description?
 ** using a separator element?
-** by convention through the element names?
+** by convention through the element names? ← ''This''
 ** as additional metadata information sent beforehand?
 * we need an object-reference element, since we do not want to copy whole subtrees while processing a diff
 
+"Objects" can be spelled out literally in code. We care to make the respective ctor syntax expressive enough. For nested objects, i.e. values of type{{{diff::Record}}}, a dedicated object builder notation is provided, (because this is the point, where the syntax gets convoluted
+
 Within this framework, we represent //object-like// entities through a special flavour of the GenNode: Basically, an object is a flat collection of children, yet given in accordance to a distinct protocol. The relevant ''meta'' information is spelled out first, followed by the ''attributes'' and finally the ''children''. The distinction between these lies in the mode of handling. Meta information is something we need to know before we're able to deal with the actual stuff. Prominent example is the type of the object. Attributes are considered unordered, and will typically be addressed by-name. Children are an ordered collection of recursive instances of the same data structure. (Incidentally, we do not rule out the possibility that also an attribute holds a recursive subtree; only the mode of access is what makes the distinction).
 
 !!!handling of actual mutation
diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm
index 0714b3e3a..8e782dbcd 100644
--- a/wiki/thinkPad.ichthyo.mm
+++ b/wiki/thinkPad.ichthyo.mm
@@ -29,23 +29,86 @@
 
 
 
-
-
+
+
 
 
 
-
+
+
+
 
 
 
 
 
-
-
+
+
+
+
+
 
 
 
-
+
+
+
+
+
+
+
+
+  
+    
+  
+  
+    

+ d.h. der usage context entscheidet, ob wir einen Wert, +

+

+ eine Referenz oder einen konstanten Wert verwenden +

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

+ Record selber ist immuable +

+

+ aber hat eine Builder-Mechanik +

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

+ eigentlich fehlte nur die get()-Operation +

+ + +
+ +
+
@@ -73,12 +136,47 @@ + + + + + + +

+ generische Lösung verschoben #963 +

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

+ C++11 erlaubt =default +

+ + +
+ +
- + + + + + + +
@@ -152,8 +250,8 @@ - - + +