|
|
|
|
@ -1992,7 +1992,7 @@ It would thus be desirable to have a fixed-sized allocation, able to hold the pl
|
|
|
|
|
!!!Storage
|
|
|
|
|
Explicit placements are value objects and stored at the respective usage site, most notably the [[Segmentation]]. They are //not// attached to the placement index in the session, nor do they bear any referential or indexing semantics. The only dynamic side effect of an explicit placement is to keep the reference count of the corresponding MObject up and thus keep it alive and accessible.</pre>
|
|
|
|
|
</div>
|
|
|
|
|
<div title="ExternalTreeDescription" creator="Ichthyostega" modifier="Ichthyostega" created="201505081647" modified="201605211638" tags="Concepts Model design spec draft" changecount="30">
|
|
|
|
|
<div title="ExternalTreeDescription" creator="Ichthyostega" modifier="Ichthyostega" created="201505081647" modified="201612031623" tags="Concepts Model design spec draft" changecount="31">
|
|
|
|
|
<pre>//to symbolically represent hierarchically structured elements, without actually implementing them.//
|
|
|
|
|
The purpose of this »external« description is to remove the need of a central data model to work against. We consider such a foundation data model as a good starting point, yet harmful for the evolution of any larger structure to be built. According to the subsidiarity principle, we prefer to turn the working data representation into a local concern. Which leaves us with the issue of collaboration. Any collaboration requires, as an underlying, some kind of common understanding. Yet any formalised, mechanical collaboration requires to represent that common point of attachment -- at least as a symbolic representation. The ExternalTreeDescription is shaped to fulfil this need: //in theory,// the whole field could be represented, symbolically, as a network of hierarchically structured elements. Yet, //in practice,// all we need is to conceive the presence of such a representation, as a backdrop to work against. And we do so -- we work against that symbolic representation, by describing ''changes'' made to the structure and its elements. Thus, the description of changes, the ''diff language'', refers to and partially embodies such symbolically represented elements and relations.
|
|
|
|
|
&rarr; TreeDiffFundamentals
|
|
|
|
|
@ -2028,7 +2028,7 @@ With the exception of the record, which, like any {{{std::vector}}} implicitly u
|
|
|
|
|
A //monad// is an entity which supports the following operations
|
|
|
|
|
*construction:{{{a:A -> M<A>(a)}}}
|
|
|
|
|
*flatMap:{{{(M<A>, f:A->M<B>) -> M<B>}}}
|
|
|
|
|
Operationally, a modad can be constructed to wrap-up and embody a given element. And to flat-map a monad generating function means to apply it to all elements within the given source monad, and then to //join// the produced monads "flat" into a new, uniform monad of the new type.
|
|
|
|
|
Operationally, a modad can be constructed to wrap-up and embody a given element. And to flat-map a monad generating function means to apply it to all "content elements" within the given source monad, and then to //join// the produced monads "flat" into a new, uniform monad of the new type.
|
|
|
|
|
Now, the interesting question is: //what does "join" mean?// --
|
|
|
|
|
*will it drill down?
|
|
|
|
|
*will it lift the contents of generated monads into the parent level, or attach them as new subtrees?
|
|
|
|
|
@ -3688,9 +3688,9 @@ As an immediate consequence of not being able to reduce processing to elementary
|
|
|
|
|
* the PlayProcess serves to join both views, providing a single PlayController front-end, while [[dispatching|FrameDispatcher]] to single channel processing.
|
|
|
|
|
</pre>
|
|
|
|
|
</div>
|
|
|
|
|
<div title="MutationMessage" creator="Ichthyostega" modifier="Ichthyostega" created="201610011953" modified="201610012003" tags="def" changecount="4">
|
|
|
|
|
<div title="MutationMessage" creator="Ichthyostega" modifier="Ichthyostega" created="201610011953" modified="201612031608" tags="def" changecount="5">
|
|
|
|
|
<pre>//message on the UI-Bus to cause changes on the targeted UI-Element.//
|
|
|
|
|
The UI-Bus offers a dedicated API to direct ~MutationMessages towards {{{Tangible}}} elements, as designated by the given ID. Actually, such messages serve as //capsule to transport a [[diff-sequence|TreeDiffModel]]// -- since a diff sequence as such is always concrete and tied to a specific context, we can not represent it directly as an abstract type on interface level. The receiver of a diff sequence must offer the ability to be reshaped through diff messages, which is expressed through the interface {{{DiffMutable}}}. In our case here, {{{Tangible}}} offers this interface and thus the ability to construct a concrete TreeMutator, which in turn is bound to the internals of the actual UI-Element in question. Together this allows for a generic implementation of MutationMessage handling, where the designated UI-Element is reshaped by applying an embedded concrete diff message with the help of a {{{DiffApplicator<DiffMutable>}}}, based on the TreeMutator exposed.</pre>
|
|
|
|
|
The UI-Bus offers a dedicated API to direct ~MutationMessages towards {{{Tangible}}} elements, as designated by the given ID. Actually, such messages serve as //capsule to transport a [[diff-sequence|TreeDiffModel]]// -- since a diff sequence as such is always concrete and tied to a specific context, we can not represent it directly as an abstract type at interface level. The receiver of a diff sequence must offer the ability to be reshaped through diff messages, which is expressed through the interface {{{DiffMutable}}}. In our case here, {{{Tangible}}} offers this interface and thus the ability to construct a concrete TreeMutator, which in turn is bound to the internals of the actual UI-Element in question. Together this allows for a generic implementation of MutationMessage handling, where the designated UI-Element is reshaped by applying an embedded concrete diff message with the help of a {{{DiffApplicator<DiffMutable>}}}, based on the TreeMutator exposed.</pre>
|
|
|
|
|
</div>
|
|
|
|
|
<div title="NodeConfiguration" modifier="Ichthyostega" created="200909041806" modified="200909041807" tags="spec Builder Rendering">
|
|
|
|
|
<pre>Various aspects of the individual [[render node|ProcNode]] are subject to configuration and may influence the output quality or the behaviour of the render process.
|
|
|
|
|
@ -8435,7 +8435,7 @@ As said, this turns out to be a tricky challenge: implementing the application o
|
|
|
|
|
** how to open a nested scope for recursive mutation
|
|
|
|
|
</pre>
|
|
|
|
|
</div>
|
|
|
|
|
<div title="TreeDiffModel" creator="Ichthyostega" modifier="Ichthyostega" created="201410270313" modified="201609050153" tags="Model GuiPattern spec draft" changecount="65">
|
|
|
|
|
<div title="TreeDiffModel" creator="Ichthyostega" modifier="Ichthyostega" created="201410270313" modified="201612031655" tags="Model GuiPattern spec draft" changecount="66">
|
|
|
|
|
<pre>for the purpose of handling updates in the GUI timeline display efficiently, we need to determine and represent //structural differences//
|
|
|
|
|
This leads to what could be considered the very opposite of data-centric programming. Instead of embody »the truth« into a central data model with predefined layout, we base our achitecture on a set of actors and their collaboration. In the mentioned example this would be the high-level view in the Session, the Builder, the UI-Bus and the presentation elements within the timeline view. Underlying to each such collaboration is a shared conception of data. There is no need to //actually represent that data// -- it can be conceived to exist in a more descriptive, declarative [[external tree description (ETD)|ExternalTreeDescription]]. In fact, what we //do represent// is a ''diff'' against such an external rendering.
|
|
|
|
|
|
|
|
|
|
@ -8482,14 +8482,14 @@ Thus, for our specific usage scenario, the foremost relevant question is //how t
|
|
|
|
|
__Implementation note__:The representation chosen here uses terms of constant size for the individual diff steps; in most cases, the argument is redundant and can be used for verification when applying the diff -- with the exception of the {{{ins}}} term, where it actually encodes additional information. Especially the {{{find}}}-representation is a compromise, since we encode as "search for the term a~~5~~ and insert it at curent position". The more obvious rendering -- "push term a~~4~~ back by +1 steps" -- requires an additional integer argument not neccesary for any of the other diff verbs, defeating a fixed size value implementation.
|
|
|
|
|
|
|
|
|
|
!!!extension to tree changes
|
|
|
|
|
Diff description and diff handling can be applied to tree-like data structures as well. Some usages of textual comparison (e.g. diffing of programming language texts) are effectively working on tree structures -- yet they do not build on the structure of the diffed data explicitly. But if we represent the data structures symbolically, the change form text diffing to data structure diffing is marginal. The only relevant change is to handle embedded recursive diff descriptions of the child nodes. As it stands, each node or "object" can be represented as a list of properties plus the attachment of child nodes. This list can be treated with the methods developed for a stream of text tokes.
|
|
|
|
|
Diff description and diff handling can be applied to tree-like data structures as well. Some usages of textual comparison (e.g. diffing of programming language texts) are effectively working on tree structures -- yet they do not build on the structure of the diffed data explicitly. But if we represent the data structures symbolically, the change form text diffing to data structure diffing is marginal. The only relevant change is to handle embedded recursive diff descriptions of the child nodes. As it stands, each node or "object" can be represented as a list of properties plus the attachment of child nodes. This list can be treated with the methods developed for a stream of text tokens.
|
|
|
|
|
|
|
|
|
|
Basically the transition from text diffing to changes on data structures is achieved by exchanging the //type of the tokens.// Instead of words, or lines of text, we now use //data elements.// To do so, we introduce a symbolic ExternalTreeDescription of tree-like core data structures. The elementary token element used in this tree diff, the GenNode, embodies either simple plain data elements (numbers, strings, booleans, id-hashes, time values) -- or it describes a //recursive data element,// given as {{{Record<GenNode>}}}. Such a recursive data element describes object-like entities as a sequence of metadata, named attributes and ordered child-nodes -- it is handled in two phases: the first step is to treat the presence and ordering of child data elements, insertions and deletes. The second phase opens for each structurally changed child data element a recursive bracketing construct, as indicated by explicit (and slightly redundant) //bracketing tokens://
|
|
|
|
|
*{{{mut}}}(node-ID) : recurse into the designated node, which must be present already as result of the preceding changes. The following diff tokens describe //mutations// of the child
|
|
|
|
|
*{{{emu}}}(node-ID) : close the current node context and return one step up; the node-ID is given for verification, but can be used to restore the working position at parent level
|
|
|
|
|
*{{{set}}}(node) : shortcut notation for simple value elements; assign the new payload value to the designated element, retaining identity
|
|
|
|
|
In addition, in a future extension, we might consider to introduce up/down folding primitives
|
|
|
|
|
*{{{fold}}}(node-ID) : pick the following elements and fold them down into a new child with given node-ID. The downfolding continues until the next {{{emu}}} token
|
|
|
|
|
*{{{fold}}}(node-ID) : pick the following elements and fold them down into a new child with given node-ID. The down folding continues until the next {{{emu}}} token
|
|
|
|
|
*{{{lift}}}(node-ID) : remove the next child node, which must be node-ID, and insert its children at current position
|
|
|
|
|
|
|
|
|
|
Since the bracketing construct for mutation of child structures bears the ID of the parent, a certain degree of leeway is introduced. In theory, we could always open such a bracketing construct right after the {{{pick}}} token accepting the parent -- yet, while minimal, such a strictly depth-first representation would be hard to read -- so we allow to group the recursive treatement of children //post-fix,// after the messages for the current node. In a similar vein, we introduce another token to describe a //short-cut://
|
|
|
|
|
@ -8498,14 +8498,28 @@ To complement this language construct, we define some special, magical (meta) el
|
|
|
|
|
*{{{_CHILD_}}} : marks an //unnamed// ID. The implementation exploits this specific marker to distinguish between nodes which are (named) attributes of an object, and real children.
|
|
|
|
|
*{{{_ATTRIBS_}}} : can be used to jump {{{after(_ATTRIBS_)}}} when mutating the contents of an object. So the following diff verbs will immediately start working on the children
|
|
|
|
|
*{{{_END_}}} : likewise can be used to jump {{{after(_END_)}}} to start appending new elements without caring for the existing current content.
|
|
|
|
|
All these additional language constructs aren't strictly necessary, but widen the usability of the langauge, also to cover the description of incomplete or fuzzy diffs.
|
|
|
|
|
All these additional language constructs aren't strictly necessary, but widen the usability of the language, also to cover the description of incomplete or fuzzy diffs.
|
|
|
|
|
|
|
|
|
|
!!!representation of objects
|
|
|
|
|
While we are talking about //structured data,// in fact what are about to handle are objects, understood in the standard flavour of object orientation, where an object is the instance of a type and offers a contract. Incidentally, this is not the original, "pure" meaning of object orientation, but the one that became prolific in brining our daily practice closer to the inherent structuring of modern human organisation. And in dealing with this kind of object, we sometimes get into conflict with the essentially open and permissive nature of structured data. So we need to establish a mapping rule, which translates into additional conventions about how to spell out matters in the diff language.
|
|
|
|
|
|
|
|
|
|
We choose to leave this largely on the level of stylistic rules, thus stressing the language nature of the diff. Even when this bears the danger to produce an exception very late, when it comes to applying the diff to a target data structure. The intention behind this whole diff approach is to transform tight coupling with strict rules into a loose collaboration based on a common understanding. So generally we'll assume the diff is just right, and if not, we'll get what we deserve.
|
|
|
|
|
|
|
|
|
|
The ''protocol to describe an object'' is as follows
|
|
|
|
|
* the ID is the objects identity and is once given, never changed
|
|
|
|
|
* we spell out any metadata (esp. a type information) first, followed by all attributes, and then followed by contents of the object's scope (children)
|
|
|
|
|
* attributes are to be given in a way not in contradiction to the more stringent semantics of an object field or property
|
|
|
|
|
** never attempt to re-order or delete such attributes, since their presence is fixed in the class definition
|
|
|
|
|
** when a field is mandatory //by its nature,// it shall be required in construction, and the corresponding data is to be given with the {{{ins}}} verb causing the constructor call
|
|
|
|
|
** on the other hand, the data for an optional field, when present, shall be spelled out by {{{ins}}} verb after construction, with the first //population diff.//
|
|
|
|
|
** we do not support attribute map semantics (or extended "object properties" of any kind). If necessary, treat them as nested entity with map semantics
|
|
|
|
|
|
|
|
|
|
!!!deriving conventional representations
|
|
|
|
|
On receiving a stream of tokens of this "diff language", it is possible to generate the well known and more conventional diff representations,
|
|
|
|
|
i.e. a ''unified diff'' or the ''predicate notation'' used above to describe the list diffing algorithm, just by accumulating changes.
|
|
|
|
|
</pre>
|
|
|
|
|
</div>
|
|
|
|
|
<div title="TreeMutator" creator="Ichthyostega" modifier="Ichthyostega" created="201503292115" modified="201610031515" tags="Model Concepts GuiPattern design draft" changecount="95">
|
|
|
|
|
<div title="TreeMutator" creator="Ichthyostega" modifier="Ichthyostega" created="201503292115" modified="201612031613" tags="Model Concepts GuiPattern design draft" changecount="98">
|
|
|
|
|
<pre>The TreeMutator is an intermediary to translate a generic structure pattern into heterogeneous local invocation sequences.
|
|
|
|
|
within the [[diff framework|TreeDiffModel]], this is a crucial joint, since here the abstract, generic, ~DOM-like ExternalTreeDescription meeds opaque, local and undisclosed data structures.
|
|
|
|
|
|
|
|
|
|
@ -8513,7 +8527,7 @@ within the [[diff framework|TreeDiffModel]], this is a crucial joint, since here
|
|
|
|
|
|
|
|
|
|
!Motivation
|
|
|
|
|
on a very large scale within the Lumiera application, disjoint subsystems are collaborating based on the notion of a //shared conceptual structure.//
|
|
|
|
|
This means, we do not share a data model -- rather we exchange ''diff messages'' with respect to this assumed, common, conceptual structure. In practice, this kind of very loose coupling is realised with the help of a ~DOM-like notation based on a small selection of primitive base types, plus an ~object-like //record// made from such base elements. Based on these elements represented as [[generic nodes|GenNode]], we can build up a symbolic representation of shared structures, which we term the ExternalTreeDescription. In fact, this is not mean and not used as actual implementation data structure -- rather it is used to derive and validate the diff messages handled within our [[diff framework|TreeDiffModel]].
|
|
|
|
|
This means, we do not share a data model -- rather we exchange ''diff messages'' with respect to this assumed, common, conceptual structure. In practice, this kind of very loose coupling is realised with the help of a ~DOM-like notation based on a small selection of primitive base types, plus an object-like //record// made from such base elements. Based on these elements represented as [[generic nodes|GenNode]], we can build up a symbolic representation of shared structures, which we term the ExternalTreeDescription. In fact, this is not meant and not used as actual implementation data structure -- rather it is used to derive and validate the diff messages handled within our [[diff framework|TreeDiffModel]].
|
|
|
|
|
|
|
|
|
|
//But --// if this symbolic representation is not meant for implementation -- how are we then able to relate it in any useful way to actual implementation data structures? The answer is two fold. For one, and most importantly, we do not collaborate on a shared data model, which means that the implementation data structures are always an implementation detail confined within some subsystem or even part of an subsystem. And this implementation layer can then -- secondly -- expose an adapter or intermediary, which offers a "generic side" for the diff framework to attach to. This adapter is the TreeMutator.
|
|
|
|
|
|
|
|
|
|
@ -8649,13 +8663,13 @@ attached to a clip, or the mixture of clips, effects and labels found within a [
|
|
|
|
|
;GenNode binding
|
|
|
|
|
:in the end, it turnes out that the //implementation// underlying our ExternalTreeDescription itself fits nicely into the above mentioned standard bindings --
|
|
|
|
|
:all we have to do is to layer two collection bindings on top of each other, with a suitable //selector// to separate //attributes// from //children.//
|
|
|
|
|
:obviously, this unified implementation comes at the price of one additional indirection (namely through the ~TreeMutator VTable), while the requirements on temporary storage size are almost identical (two iterators and two back references instead of one). Moreover, all the explicitly coded complexities regarding the attribute / children distinction is gone, relying on the logic of layered decorators solely. So the effort to shape the TreeMutator API payed off in the end, to improve and rectify the whole design...
|
|
|
|
|
:obviously, this unified implementation comes at the price of one additional indirection (namely through the ~TreeMutator ~VTable), while the requirements on temporary storage size are almost identical (two iterators and two back references instead of one). Moreover, all the explicitly coded complexities regarding the attribute / children distinction is gone, relying on the logic of layered decorators solely. So the effort to shape the TreeMutator API payed off in the end, to improve and rectify the whole design...
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
You should note that this entire design is recursive: only after understanding the part, where, for handling a sub-structure, a nested mutator is fabricated and placed into a given buffer, it becomes clear to what effect we're creating a customised mutator: we always need some (relative) parent scope, which happens to know more about the actual data to be treated with a TreeMutator. This scope assists with creating a suitable binding. Obviously, from within that binding, it is known what the sub-structures and children of that local data are all about and what semantics to give to the fundamental operations.
|
|
|
|
|
</pre>
|
|
|
|
|
</div>
|
|
|
|
|
<div title="TreeMutatorEvolution" creator="Ichthyostega" modifier="Ichthyostega" created="201603160255" modified="201610031511" tags="Model Concepts design draft" changecount="26">
|
|
|
|
|
<div title="TreeMutatorEvolution" creator="Ichthyostega" modifier="Ichthyostega" created="201603160255" modified="201612031824" tags="Model Concepts design draft" changecount="29">
|
|
|
|
|
<pre>The TreeMutator is an intermediary to translate a generic structure pattern into heterogeneous local invocation sequences.
|
|
|
|
|
|
|
|
|
|
!Motivation
|
|
|
|
|
@ -8708,7 +8722,7 @@ This construction pattern can be extended to offer several optional extension ho
|
|
|
|
|
* how to deal with collections of children
|
|
|
|
|
* how to integrate typed children
|
|
|
|
|
|
|
|
|
|
&rarr; largely, these problems are settled {{red{as of 3/2013}}}
|
|
|
|
|
&rarr; largely, these problems are settled {{red{as of 3/2016}}}
|
|
|
|
|
;objects
|
|
|
|
|
:...are represented within the fixed structures of the [[ETD|ExternalTreeDescription]], that is as combination of [[generic node elements|GenNode]]
|
|
|
|
|
;binding
|
|
|
|
|
@ -8798,6 +8812,11 @@ To create a ''binding'' for any object field, we need
|
|
|
|
|
* either a ''setter'' (lambda) or a ''mutator builder'' (lambda)
|
|
|
|
|
We have a distinct typing for each individual attribute, but this typing remains implicit: the lambda has to know what value to extract from the GenNode payload within the accepted diff message and how to apply this value. Especially for ''time entities'', which are modelled as immutable values, the lambda might want to build a [[time mutator|TimeMutation]]. And especially in the UI, timing specifications are expected to be translated into a //presentation grid.//
|
|
|
|
|
|
|
|
|
|
!!!policy to deal with non optional object fields
|
|
|
|
|
It turns out we're frequently forced to make a problematic decision here: in practice we often have the choice to treat a field as optional or mandatory. The diff protocol demands to send all mandatory fields immediately, with the {{{INS}}} verb causing object creation, but, generally speaking, both cases can be supported. Now, what makes this decision tough is the fact it seems way more cheap to cheat our way around this decision: we may implement the fields as being optional, but actually treat them as being mandatory. And we just hope the diff will always provide the necessary values with further {{{INS}}} verbs right within the first population diff. Judging by widely accepted principles of pragmatism, this way to deal with the problem is even the most sensible way. Incidentally, this also relates to the pervasive use of property setters and getters in typical object based programming.
|
|
|
|
|
Unfortunately, there is a price to pay on the long run. This fudge tends to spread in neighbouring code, and, over time, what is //practically irrelevant// tends to happen non the less, causing fixes and complexities to creep into the code. A good guideline thus is not to base this decision on practicality, but to base it on the nature of those matters to be represented in objects: is something //by its own nature is mandatory,// then represent it as mandatory. If something is optional, maybe try to decompose to get rid of it altogether.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!!!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 a type field in {{{diff::Record}}}, which is treated explicitly).
|
|
|
|
|
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.
|
|
|
|
|
@ -8818,7 +8837,7 @@ To receive and apply a diff, client code has to build a {{{DiffApplicator<Tre
|
|
|
|
|
|
|
|
|
|
The {{{DiffApplicator}}} itself can be made non-copyable; preferably it should be small and cheap to construct. At least we should strive at keeping the number of indirections and heap allocations low. Together with the requirement to separate from the actual TreeMutator implementation, which is built late, just before invocation, we arrive at a ~PImpl structure, with the TreeMutator as ~PImpl and a scope manager hidden within the implementation part; the latter will be responsible for creating a suitable stack, and to use the //mutator building closure// in order to incorporate the concrete TreeMutator into the stack frames.
|
|
|
|
|
|
|
|
|
|
Pulling all those building blocks together, this architecture finally allows us to offer a (tree) diff-applicator for //»basically anything«:// The ctor respective the init method of {{{DiffAplicator<Something>}}} relies on the metaprogramming or ADL technique embedded within the {{{TreeDiffTraits<Something>}}} to //somehow// get at a {{{DiffMutable&}}} -- the latter offering the crucial method to build a TreeMutator implementation internally wired in a proper way to {{{Something}}}'s internals. This in turn enables us to build a suitalbe {{{ScopeManager}}} implementation with a stack size sufficient to hold this TreeMutator implementation. After this type specific setup, the rest of the diff application works entirely generic and can thus be delegated to the non-templated baseclass TreeDiffMutatorBinding...
|
|
|
|
|
Pulling all those building blocks together, this architecture finally allows us to offer a (tree) diff-applicator for //»basically anything«:// The ctor respective the init method of {{{DiffAplicator<Something>}}} relies on the metaprogramming or ADL technique embedded within the {{{TreeDiffTraits<Something>}}} to //somehow// get at a {{{DiffMutable&}}} -- the latter offering the crucial method to build a TreeMutator implementation internally wired in a proper way to {{{Something}}}'s internals. This in turn enables us to build a suitalbe {{{ScopeManager}}} implementation with a stack size sufficient to hold this TreeMutator implementation. After this type specific setup, the rest of the diff application works entirely generic and can thus be delegated to the non-templated baseclass {{{TreeDiffMutatorBinding}}}...
|
|
|
|
|
</pre>
|
|
|
|
|
</div>
|
|
|
|
|
<div title="TypedID" modifier="Ichthyostega" created="201003200157" modified="201505310143" tags="Model Types Rules design draft" changecount="12">
|
|
|
|
|
|