|
|
|
@ -1970,7 +1970,7 @@ It would thus be desirable to have a fixed-sized allocation, able to hold the pl
|
|
|
|
!!!Storage
|
|
|
|
!!!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>
|
|
|
|
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>
|
|
|
|
<div title="ExternalTreeDescription" creator="Ichthyostega" modifier="Ichthyostega" created="201505081647" modified="201505090059" tags="Concepts Model design spec draft" changecount="19">
|
|
|
|
<div title="ExternalTreeDescription" creator="Ichthyostega" modifier="Ichthyostega" created="201505081647" modified="201506041327" tags="Concepts Model design spec draft" changecount="21">
|
|
|
|
<pre>//to symbolically represent hierarchically structured elements, without actually implementing them.//
|
|
|
|
<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. And any formalised, mechanical collaboration requires to represent that common point of attachment -- at least as 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.
|
|
|
|
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. And any formalised, mechanical collaboration requires to represent that common point of attachment -- at least as 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
|
|
|
|
&rarr; TreeDiffFundamentals
|
|
|
|
@ -2019,7 +2019,7 @@ This decision more or less limits the usefulness of simple values as children to
|
|
|
|
The discriminating ID of any GenNode can serve as a name, and indeed will be used as the name of an attribute within a record.
|
|
|
|
The discriminating ID of any GenNode can serve as a name, and indeed will be used as the name of an attribute within a record.
|
|
|
|
Now, the interesting question is: what constitues the full identity? Is it the ~ID-string? does it also include some kind of type information, so that two children with the same name, but different types would be considered different? And, moreover, we could even go as far as to make the path part of the identity, so that two otherwise identical elements would be different, when located at different positions within the graph. But since we did not rule out cyclic graphs, the latter idea would necessitate the notion of an //optimal path// --
|
|
|
|
Now, the interesting question is: what constitues the full identity? Is it the ~ID-string? does it also include some kind of type information, so that two children with the same name, but different types would be considered different? And, moreover, we could even go as far as to make the path part of the identity, so that two otherwise identical elements would be different, when located at different positions within the graph. But since we did not rule out cyclic graphs, the latter idea would necessitate the notion of an //optimal path// --
|
|
|
|
|
|
|
|
|
|
|
|
A somewhat similar question is the ordering and uniqueness of children. While attributes -- due to the usage of the attribute node's ID as name-key -- are bound to be unique within a given Record, children within the scope of a record could be required to be unique too, making the scope a set. And, of course, children could be focribly ordered, or just retaining the initial ordering, or even be completely unordered. On a second thought, it seems wise not to impose any guarantees in that regard, beyond the simple notion of retaining an initial sequence order. All these more specific ordering properties can be considered the concern of some specific kinds of objects -- which then just happen to "supply" a list of children for symbolic representation as they see fit.
|
|
|
|
A somewhat similar question is the ordering and uniqueness of children. While attributes -- due to the usage of the attribute node's ID as name-key -- are bound to be unique within a given Record, children within the scope of a record could be required to be unique too, making the scope a set. And, of course, children could be focribly ordered, or just retain the initial ordering, or even be completely unordered. On a second thought, it seems wise not to impose any guarantees in that regard, beyond the simple notion of retaining an initial sequence order, the way a »stable« sorting algorithm does. All these more specific ordering properties can be considered the concern of some specific kinds of objects -- which then just happen to "supply" a list of children for symbolic representation as they see fit.
|
|
|
|
</pre>
|
|
|
|
</pre>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div title="Factories" modifier="Ichthyostega" created="200708100401" modified="201310132317" tags="def Concepts" changecount="6">
|
|
|
|
<div title="Factories" modifier="Ichthyostega" created="200708100401" modified="201310132317" tags="def Concepts" changecount="6">
|
|
|
|
@ -2316,9 +2316,9 @@ For this Lumiera design, we could consider making GOP just another raw media dat
|
|
|
|
&rarr;see in [[Wikipedia|http://en.wikipedia.org/wiki/Group_of_pictures]]
|
|
|
|
&rarr;see in [[Wikipedia|http://en.wikipedia.org/wiki/Group_of_pictures]]
|
|
|
|
</pre>
|
|
|
|
</pre>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div title="GenNode" creator="Ichthyostega" modifier="Ichthyostega" created="201501171413" modified="201505081546" tags="Model GuiIntegration GuiPattern def draft" changecount="11">
|
|
|
|
<div title="GenNode" creator="Ichthyostega" modifier="Ichthyostega" created="201501171413" modified="201505312131" tags="Model GuiIntegration GuiPattern def draft" changecount="12">
|
|
|
|
<pre>//Abstract generic node element to build a ~DOM-like rendering of Lumiera's [[session model|HighLevelModel]].//
|
|
|
|
<pre>//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 point of reference 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.
|
|
|
|
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]]).
|
|
|
|
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''.
|
|
|
|
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''.
|
|
|
|
@ -2444,7 +2444,7 @@ The workspace starts out with a single element, corresponding to the »model roo
|
|
|
|
Speaking of implementation, this state and update mechanics relies on two crucial provisions: Lumiera's framework for [[tree diff representation|TreeDiffModel]] and the ExternalTreeDescription, which is an abstracted, ~DOM-like rendering of the relevant parts of the session; this model tree is comprised of [[generic node elements|GenNode]] acting as proxy for [[calls into|SessionInterface]] the [[session model|HighLevelModel]] proper.
|
|
|
|
Speaking of implementation, this state and update mechanics relies on two crucial provisions: Lumiera's framework for [[tree diff representation|TreeDiffModel]] and the ExternalTreeDescription, which is an abstracted, ~DOM-like rendering of the relevant parts of the session; this model tree is comprised of [[generic node elements|GenNode]] acting as proxy for [[calls into|SessionInterface]] the [[session model|HighLevelModel]] proper.
|
|
|
|
</pre>
|
|
|
|
</pre>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div title="GuiModelUpdate" creator="Ichthyostega" modifier="Ichthyostega" created="201410250121" modified="201503221633" tags="GuiIntegration GuiPattern design decision discuss draft" changecount="30">
|
|
|
|
<div title="GuiModelUpdate" creator="Ichthyostega" modifier="Ichthyostega" created="201410250121" modified="201506040022" tags="GuiIntegration GuiPattern design decision discuss draft" changecount="31">
|
|
|
|
<pre>Considerations regarding the [[structure of custom timeline widgets|GuiTimelineWidgetStructure]] highlight again the necessity of a clean separation of concerns and an "open closed design". For the purpose of updating the timeline(s) to reflect the HighLevelModel in Proc-Layer, several requirements can be identified
|
|
|
|
<pre>Considerations regarding the [[structure of custom timeline widgets|GuiTimelineWidgetStructure]] highlight again the necessity of a clean separation of concerns and an "open closed design". For the purpose of updating the timeline(s) to reflect the HighLevelModel in Proc-Layer, several requirements can be identified
|
|
|
|
* we need incremental updates: we must not start redrawing each and everything on each tiny change
|
|
|
|
* we need incremental updates: we must not start redrawing each and everything on each tiny change
|
|
|
|
* we need recursive programming, since this is the only sane way to deal with tree like nested structures.
|
|
|
|
* we need recursive programming, since this is the only sane way to deal with tree like nested structures.
|
|
|
|
@ -2479,6 +2479,9 @@ A relevant question to be settled is as to where the core of each change is cons
|
|
|
|
* we might, at the moment of performing the update, acquire a lock from the ProcDispatcher. The update process may then effectively query down into the session datastructure proper, even through the proxy of a diffing process. The obvious downside is that GUI response might block waiting on an extended operation in Proc, especially when a new build process was started meanwhile. A remedy might be to abort the update in such cases, since its effects will be obsoleted by the build process anyway.
|
|
|
|
* we might, at the moment of performing the update, acquire a lock from the ProcDispatcher. The update process may then effectively query down into the session datastructure proper, even through the proxy of a diffing process. The obvious downside is that GUI response might block waiting on an extended operation in Proc, especially when a new build process was started meanwhile. A remedy might be to abort the update in such cases, since its effects will be obsoleted by the build process anyway.
|
|
|
|
* alternatively, we might incorporate a complete snapshot of all information relevant for the GUI into the GuiModel. Update messages from Proc must be complete and self contained in this case, since our goal is to avoid callbacks. Following this scheme, the first stage of any update would be a push from Proc to the GuiModel, followed by a callback pull from within the individual widgets receiving the notification later. This is the approach we choose for the Lumiera GUI.
|
|
|
|
* alternatively, we might incorporate a complete snapshot of all information relevant for the GUI into the GuiModel. Update messages from Proc must be complete and self contained in this case, since our goal is to avoid callbacks. Following this scheme, the first stage of any update would be a push from Proc to the GuiModel, followed by a callback pull from within the individual widgets receiving the notification later. This is the approach we choose for the Lumiera GUI.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!!!information to represent and to derive
|
|
|
|
|
|
|
|
The purpose of the GuiModel is to represent an anchor point for the structures //actually relevant for the UI.// To put that into context, the model in the session is not bound to represent matters exactly in the way to be rendered within the GUI. All we can expect is for the //build process// -- upon completion -- to generate a view of the actually altered parts, detailing the information relevant for presentation. Thus we do retain an ExternalTreeDescription of all the information received this way within the GuiModel. Whenever a completed build process sends an updated state, we use the diff framework to determine the actually relevant differences -- both for triggering the corresponding GUI widgets, and for forwarding this focussed diff information to these widgets when they call back from the UI event thread to pull the actual changes.
|
|
|
|
|
|
|
|
|
|
|
|
!!!switch of typed sub-context
|
|
|
|
!!!switch of typed sub-context
|
|
|
|
When dealing with structural (tree) diffing, there is a specific twist regarding child nodes of mixed type: In the general case, we can not assume that all children of a given node are of the same kind. The classical example is (X)HTML, where a node has //attributes,// various //nested tags// and //nested text content.// The //generic node// thus must be modelled as having several collections of children -- both ordered and un-ordered collections are possible -- and the content of each such sub-collection is itself polymorphic. This constitutes a challenge for the representation of data within the tree diff format. These difficulties can be overcome as follows
|
|
|
|
When dealing with structural (tree) diffing, there is a specific twist regarding child nodes of mixed type: In the general case, we can not assume that all children of a given node are of the same kind. The classical example is (X)HTML, where a node has //attributes,// various //nested tags// and //nested text content.// The //generic node// thus must be modelled as having several collections of children -- both ordered and un-ordered collections are possible -- and the content of each such sub-collection is itself polymorphic. This constitutes a challenge for the representation of data within the tree diff format. These difficulties can be overcome as follows
|
|
|
|
#anything, even nested "raw" content is represented //as node//
|
|
|
|
#anything, even nested "raw" content is represented //as node//
|
|
|
|
@ -7514,7 +7517,7 @@ Thus no server and no network connection is needed. Simply open the file in your
|
|
|
|
* see [[Homepage|http://tiddlywiki.com]], [[Wiki-Markup|http://tiddlywiki.org/wiki/TiddlyWiki_Markup]]
|
|
|
|
* see [[Homepage|http://tiddlywiki.com]], [[Wiki-Markup|http://tiddlywiki.org/wiki/TiddlyWiki_Markup]]
|
|
|
|
</pre>
|
|
|
|
</pre>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div title="TimeMutation" modifier="Ichthyostega" created="201101231344" modified="201105261700" tags="spec discuss draft">
|
|
|
|
<div title="TimeMutation" modifier="Ichthyostega" created="201101231344" modified="201506032222" tags="spec discuss draft" changecount="1">
|
|
|
|
<pre>Simple time points are just like values and thus easy to change. The difficulties arise when time values are to be //quantised to an existing time grid.// The first relevant point to note is that for quantised time values, the effect of a change can be disproportional to the cause. Small changes below the threshold might be accumulated, and a tiny change might trigger a jump to the next grid point. While this might be annoying, the yet more complex questions arise when we acknowledge that the amount of the change itself might be related to a time grid.
|
|
|
|
<pre>Simple time points are just like values and thus easy to change. The difficulties arise when time values are to be //quantised to an existing time grid.// The first relevant point to note is that for quantised time values, the effect of a change can be disproportional to the cause. Small changes below the threshold might be accumulated, and a tiny change might trigger a jump to the next grid point. While this might be annoying, the yet more complex questions arise when we acknowledge that the amount of the change itself might be related to a time grid.
|
|
|
|
|
|
|
|
|
|
|
|
The problem with modification of quantised values highlights an inner contradiction or conflicting goals within the design
|
|
|
|
The problem with modification of quantised values highlights an inner contradiction or conflicting goals within the design
|
|
|
|
@ -7590,7 +7593,7 @@ Rationale: allowing mutations for Time bears the danger of making ~TimeVar obsol
|
|
|
|
* err, because MObject will include a Duration separate from the start time in the Placement, Duration needs to be mutable too
|
|
|
|
* err, because MObject will include a Duration separate from the start time in the Placement, Duration needs to be mutable too
|
|
|
|
|
|
|
|
|
|
|
|
!!!usage considerations
|
|
|
|
!!!usage considerations
|
|
|
|
{{red{Question 5/11}}} when moving a clip taken from 50fps media, the new position might be quantised to the 50fps grid established by the media, while the target timeline runs with 25fps, allowing for finer adjustments based on the intermediate frames present in the source material.
|
|
|
|
{{red{Question 5/11}}} when moving a clip taken from 50fps media, the new position might be quantised to the 50fps grid established by the media, even when the target timeline runs with 25fps, allowing for finer adjustments based on the intermediate frames present in the source material.
|
|
|
|
|
|
|
|
|
|
|
|
!!!design draft
|
|
|
|
!!!design draft
|
|
|
|
The special focus of this problem seems to lead itself to a __visitor pattern__ based implementation. Because the basic hierarchy of applicable types is fixed, but the behaviour is open ended (and not yet fully determined). A conventional implementation would scatter this behaviour over all the time entities, thus making it hard to understand and reason about. The classical ~GoF cyclic visitor solution to the contrary allows us to arrange closely related behaviour into thematically grouped visitor classes. As a plus, the concrete action can be bound dynamically, allowing for more flexibility when it comes to dealing with the intricate situations when a quantised time span (= a clip) recieves a quantised mutation (= is re-alligend to a possibly different frame grid)
|
|
|
|
The special focus of this problem seems to lead itself to a __visitor pattern__ based implementation. Because the basic hierarchy of applicable types is fixed, but the behaviour is open ended (and not yet fully determined). A conventional implementation would scatter this behaviour over all the time entities, thus making it hard to understand and reason about. The classical ~GoF cyclic visitor solution to the contrary allows us to arrange closely related behaviour into thematically grouped visitor classes. As a plus, the concrete action can be bound dynamically, allowing for more flexibility when it comes to dealing with the intricate situations when a quantised time span (= a clip) recieves a quantised mutation (= is re-alligend to a possibly different frame grid)
|
|
|
|
@ -7940,7 +7943,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
|
|
|
|
:Chunks of raw data are attached inline to the structural diff, assuming that each element implicitly knows the kind of data to expect
|
|
|
|
</pre>
|
|
|
|
</pre>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div title="TreeDiffImplementation" creator="Ichthyostega" modifier="Ichthyostega" created="201412210015" modified="201504290114" tags="Model GuiPattern design draft" changecount="31">
|
|
|
|
<div title="TreeDiffImplementation" creator="Ichthyostega" modifier="Ichthyostega" created="201412210015" modified="201506040013" tags="Model GuiPattern design draft" changecount="33">
|
|
|
|
<pre>//This page details decisions taken for implementation of Lumiera's diff handling framework//
|
|
|
|
<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.
|
|
|
|
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.
|
|
|
|
|
|
|
|
|
|
|
|
@ -7993,6 +7996,16 @@ This design prefers the //pull// approach, with a special twist: we provide a co
|
|
|
|
!!!representation of objects
|
|
|
|
!!!representation of objects
|
|
|
|
It should be noted, that the purpose of this whole architecture is to deal with »remote« stuff -- things we somehow need to refer and deal with, but nothing we can influence immediately, right here: every actual manipulation has to be turned into a message and sent //elsewhere.// This is the only context, where some, maybe even partial, generic and introspective object representation makes sense.
|
|
|
|
It should be noted, that the purpose of this whole architecture is to deal with »remote« stuff -- things we somehow need to refer and deal with, but nothing we can influence immediately, right here: every actual manipulation has to be turned into a message and sent //elsewhere.// This is the only context, where some, maybe even partial, generic and introspective object representation makes sense.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{{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 represent the break between attributes and children in this linearised description?
|
|
|
|
|
|
|
|
** using a separator element?
|
|
|
|
|
|
|
|
** by convention through the element names?
|
|
|
|
|
|
|
|
** 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
|
|
|
|
|
|
|
|
|
|
|
|
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).
|
|
|
|
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
|
|
|
|
!!!handling of actual mutation
|
|
|
|
@ -8064,7 +8077,7 @@ On receiving the terms of this "diff language", it is possible to gene
|
|
|
|
i.e. a ''unified diff'' or the ''predicate notation'' used above to describe the list diffing algorithm, just by accumulating changes.
|
|
|
|
i.e. a ''unified diff'' or the ''predicate notation'' used above to describe the list diffing algorithm, just by accumulating changes.
|
|
|
|
</pre>
|
|
|
|
</pre>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div title="TreeMutator" creator="Ichthyostega" modifier="Ichthyostega" created="201503292115" modified="201505310130" tags="Model Concepts GuiPattern design draft" changecount="50">
|
|
|
|
<div title="TreeMutator" creator="Ichthyostega" modifier="Ichthyostega" created="201503292115" modified="201505312250" tags="Model Concepts GuiPattern design draft" changecount="52">
|
|
|
|
<pre>The TreeMutator is an intermediary to translate a generic structure pattern into heterogeneous local invocation sequences.
|
|
|
|
<pre>The TreeMutator is an intermediary to translate a generic structure pattern into heterogeneous local invocation sequences.
|
|
|
|
|
|
|
|
|
|
|
|
!Motivation
|
|
|
|
!Motivation
|
|
|
|
@ -8117,7 +8130,7 @@ This construction pattern can be extended to offer several optional extension ho
|
|
|
|
* how to integrate typed children
|
|
|
|
* how to integrate typed children
|
|
|
|
|
|
|
|
|
|
|
|
!!!working with children
|
|
|
|
!!!working with children
|
|
|
|
Handling tree structured object data imposes some additional constraints, in comparision to generic changes done to a flat list. One notable difference is that there are pre-existing //attributes,// which can not be added and deleted, are known by-name, not by positional order. Another point worth noting is the fact that child objects may be segregated into several collections by type. Since our goal is to provide an intermediary with the ability to map to arbitrary structures, we need to define the primitive operations necessary for implementing the structural operations represented in the form of a diff
|
|
|
|
Handling tree structured object data imposes some additional constraints, in comparision to generic changes done to a flat list. One notable difference is that there are pre-existing //attributes,// which can not be added and deleted, are known by-name, not by positional order. Another point worth noting is the fact that child objects may be segregated into several collections by type. Since our goal is to provide an intermediary with the ability to map to arbitrary structures, we need to define the primitive operations necessary for implementing the concrete structural operations represented in the form of a diff
|
|
|
|
* add a child
|
|
|
|
* add a child
|
|
|
|
* remove a child
|
|
|
|
* remove a child
|
|
|
|
* step to the next child
|
|
|
|
* step to the next child
|
|
|
|
@ -8129,7 +8142,7 @@ All these basic operations are implicitly stateful, i.e. they work against an as
|
|
|
|
To ease the repetitive part of the wiring, which is necessary for each individual application case, we can allow for some degree of //duck typing,// as far as building the TreeMutator is concerned. If there is a type, which provides the above mentioned functions for child management, these can be hooked up automatically into a suitable adapter. Otherwise, the client may supply closures, using the same definition pattern as shown for the attributes above. Here, the ID argument is optional and denotes a //type filter,// whereas the closure itself must accept a name-ID argument. The purpose of this construction is the ability to manage collections of similar children. For example
|
|
|
|
To ease the repetitive part of the wiring, which is necessary for each individual application case, we can allow for some degree of //duck typing,// as far as building the TreeMutator is concerned. If there is a type, which provides the above mentioned functions for child management, these can be hooked up automatically into a suitable adapter. Otherwise, the client may supply closures, using the same definition pattern as shown for the attributes above. Here, the ID argument is optional and denotes a //type filter,// whereas the closure itself must accept a name-ID argument. The purpose of this construction is the ability to manage collections of similar children. For example
|
|
|
|
{{{
|
|
|
|
{{{
|
|
|
|
.addChild("Fork"), [&](string type, string id) {
|
|
|
|
.addChild("Fork"), [&](string type, string id) {
|
|
|
|
ForkType kind = determineForkkType(type);
|
|
|
|
ForkType kind = determineForkType(type);
|
|
|
|
this.forks_.push_back(MyForkImpl(kind, id);
|
|
|
|
this.forks_.push_back(MyForkImpl(kind, id);
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.mutateChild("Fork"), [&](string id) {
|
|
|
|
.mutateChild("Fork"), [&](string id) {
|
|
|
|
|