WIP: stub GenNode ref

This commit is contained in:
Fischlurch 2015-07-04 20:50:18 +02:00
parent ee6d044e33
commit 5b0d58518e
6 changed files with 120 additions and 14 deletions

View file

@ -33,6 +33,7 @@
#include "lib/error.hpp"
#include "lib/diff/diff-language.hpp"
#include "lib/diff/gen-node.hpp"
namespace lib {
@ -40,5 +41,14 @@ namespace diff{
LUMIERA_ERROR_DEFINE(DIFF_CONFLICT, "Collision in diff application: contents of target not as expected.");
/* symbolic marker ID references
* used the tree diff language
* to mark specific scopes
*/
Ref Ref::END ("_END_");
Ref Ref::THIS ("_THIS_");
Ref Ref::CHILD ("_CHILD_");
Ref Ref::ATTRIBS("_ATTRIBS_");
}} // namespace lib::diff

View file

@ -123,6 +123,7 @@ namespace diff{
class GenNode;
using Rec = Record<GenNode>;
using RecRef = RecordRef<GenNode>;
using MakeRec = Rec::Mutator;
using DataValues = meta::Types<int
,int64_t
@ -136,6 +137,7 @@ namespace diff{
,time::Duration
,time::TimeSpan
,hash::LuidH
,RecRef
,Rec
>;
@ -266,6 +268,21 @@ namespace diff{
}
protected:
/** @internal for dedicated builder subclasses */
GenNode (ID&& id, DataCap&& d)
: idi(std::move(id))
, data(std::move(d))
{ }
template<typename X>
static GenNode::ID
fabricateRefID (string const& symbolicID)
{
X* typeID;
return ID(typeID, symbolicID);
}
private:
template<typename X>
static string
@ -276,6 +293,39 @@ namespace diff{
};
/**
* Constructor for a specially crafted 'ref GenNode'.
* The identity record of the generated object will be prepared
* such as to be identical to a regular GenNode with Record payload.
* @note slicing in usage is intentional
*/
struct Ref
: GenNode
{
/** create an empty ID stand-in.
* @note the purpose is to create a symbolic reference by name
*/
explicit
Ref(string const& symbolicID)
: GenNode(fabricateRefID<RecRef> (symbolicID)
, DataCap(RecRef())) // note: places NIL into the reference part
{ }
/** build reference to a Record, using the original ID
* @throw error::Logic when oNode does not hold a Record<GenNode>
*/
Ref(GenNode& oNode)
: GenNode(ID(oNode)
, DataCap(RecRef(oNode.data.get<Rec>())))
{ }
static Ref END; ///< symbolic ID ref "_END_"
static Ref THIS; ///< symbolic ID ref "_THIS_"
static Ref CHILD; ///< symbolic ID ref "_CHILD_"
static Ref ATTRIBS; ///< symbolic ID ref "_ATTRIBS_"
};
/* === Specialisation to add fluent GenNode builder API to Record<GenNode> === */

View file

@ -485,6 +485,12 @@ namespace diff{
explicit
operator bool() const
{
return empty();
}
bool
empty() const
{
return bool(record_);
}

View file

@ -223,8 +223,8 @@ namespace test{
CHECK (hamID.getHash() == ham.idi.getHash());
CHECK (contains (string(hamID), "spam")); // Lovely spam!
GenNode ref1 = Ref("egg bacon sausage and spam");
GenNode ref2 = Ref(ham);
Ref ref1("egg bacon sausage and spam");
Ref ref2(ham);
CHECK (ref1.idi == ham.idi);
CHECK (ref2.idi == ham.idi);
@ -233,8 +233,8 @@ namespace test{
CHECK (isSameObject (ham, ref2.data.get<Rec>()));
VERIFY_ERROR (BOTTOM_VALUE, ref1.data.get<Rec>());
RecordRef rr1 = ref1.data.get<RecordRef>();
RecordRef rr2 = ref2.data.get<RecordRef>();
RecRef rr1 = ref1.data.get<RecRef>();
RecRef rr2 = ref2.data.get<RecRef>();
CHECK ( isnil(rr1));
CHECK (!isnil(rr2));
@ -248,10 +248,10 @@ namespace test{
CHECK ("_CHILD_" == name(Ref::CHILD));
CHECK ("_ATTRIBS_" == name(Ref::ATTRIBS));
CHECK (isnil (Ref::END.data.get<RecordRef>()));
CHECK (isnil (Ref::THIS.data.get<RecordRef>()));
CHECK (isnil (Ref::CHILD.data.get<RecordRef>()));
CHECK (isnil (Ref::ATTRIBS.data.get<RecordRef>()));
CHECK (isnil (Ref::END.data.get<RecRef>()));
CHECK (isnil (Ref::THIS.data.get<RecRef>()));
CHECK (isnil (Ref::CHILD.data.get<RecRef>()));
CHECK (isnil (Ref::ATTRIBS.data.get<RecRef>()));
}

View file

@ -7947,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
</pre>
</div>
<div title="TreeDiffImplementation" creator="Ichthyostega" modifier="Ichthyostega" created="201412210015" modified="201507031715" tags="Model GuiPattern design draft" changecount="36">
<div title="TreeDiffImplementation" creator="Ichthyostega" modifier="Ichthyostega" created="201412210015" modified="201507041449" tags="Model GuiPattern design draft" changecount="38">
<pre>//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.
@ -8010,7 +8010,7 @@ It should be noted, that the purpose of this whole architecture is to deal with
** 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
&quot;Objects&quot; 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
&quot;Objects&quot; 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).

View file

@ -325,8 +325,8 @@
<node CREATED="1434128393429" ID="ID_1275202366" MODIFIED="1434128584214" TEXT="mu&#xdf; GenNode sein">
<icon BUILTIN="idea"/>
</node>
<node CREATED="1434128412934" ID="ID_1319614474" MODIFIED="1434128461227" TEXT="Repr&#xe4;s entscheiden">
<icon BUILTIN="pencil"/>
<node CREATED="1434128412934" ID="ID_1319614474" MODIFIED="1436021920247" TEXT="Repr&#xe4;s entscheiden">
<icon BUILTIN="go"/>
<node CREATED="1434128438565" ID="ID_913220298" MODIFIED="1434128678545" TEXT="als ID erkennbar">
<richcontent TYPE="NOTE"><html>
<head>
@ -345,8 +345,10 @@
<node CREATED="1434128779661" ID="ID_1739097548" MODIFIED="1434236311060" TEXT="marker-ID + string-Payload">
<icon BUILTIN="button_cancel"/>
</node>
<node CREATED="1434128917125" ID="ID_392407967" MODIFIED="1434238970157" TEXT="&quot;fehlkonstruierte&quot; ID + pr&#xfc;f-Pr&#xe4;dikat"/>
<node CREATED="1434128981381" ID="ID_101281763" MODIFIED="1434236527554" TEXT="spezielle Ref-Payload">
<node CREATED="1434128917125" ID="ID_392407967" MODIFIED="1436021562160" TEXT="&quot;fehlkonstruierte&quot; ID + pr&#xfc;f-Pr&#xe4;dikat">
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1434128981381" ID="ID_101281763" MODIFIED="1436021564745" TEXT="spezielle Ref-Payload">
<richcontent TYPE="NOTE"><html>
<head>
@ -357,6 +359,41 @@
</p>
</body>
</html></richcontent>
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1436021576224" ID="ID_1239136010" MODIFIED="1436021889094" TEXT="Begr&#xfc;ndung">
<font NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="idea"/>
<node CREATED="1436021581655" ID="ID_124352424" MODIFIED="1436021603779" TEXT="hash-identische ID sorgt f&#xfc;r transparente Integration"/>
<node CREATED="1436021610648" ID="ID_1621632066" MODIFIED="1436021618067" TEXT="das nimmt Komplexit&#xe4;t aus der Anwendung heraus"/>
<node CREATED="1436021623799" ID="ID_929212705" MODIFIED="1436021637115" TEXT="f&#xfc;r die Dereferenzierung zahlt nur die Referenz"/>
<node CREATED="1436021694039" ID="ID_1657867881" MODIFIED="1436021817445" TEXT="Nachteil ist Gefahr der Verwirrung">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
gemeint ist:
</p>
<ul>
<li>
man kann alternativ auch eine RecordRef direkt in eine elementare GenNode packen
</li>
<li>
diese verh&#228;lt sich dann nicht transparent, denn sie hat eine andere Identit&#228;t als ihr Ziel
</li>
<li>
das kann aber als spezielles Ausdrucksmittel genutzt werden
</li>
</ul>
</body>
</html>
</richcontent>
</node>
<node CREATED="1436021719055" ID="ID_1039111553" MODIFIED="1436021730099" TEXT="ist nur ein halber Nachteil"/>
<node CREATED="1436021731615" ID="ID_1576857183" MODIFIED="1436021741970" TEXT="kann n&#xe4;mlich auch Ausdrucksmittel sein"/>
<node CREATED="1436021848790" ID="ID_742066846" MODIFIED="1436021874042" TEXT="problematisch ist die Implementerung des Erkennungs-Pr&#xe4;dikates"/>
</node>
</node>
</node>
@ -473,6 +510,9 @@
</html></richcontent>
<icon BUILTIN="idea"/>
</node>
<node CREATED="1436019533354" ID="ID_1500539399" MODIFIED="1436019542698" TEXT="Konzept-Bruch">
<icon BUILTIN="yes"/>
</node>
</node>
</node>
</node>