Commit graph

3273 commits

Author SHA1 Message Date
e7d284783b Inv(#1020): place widgets on canvas
- randomly
- partially overlapping
- event dispatch works as expected
2016-10-28 17:32:43 +02:00
5897d1ffad clean-up: unnecessary includes
they'll hamper the investigation by causing extended compilation round-trip
2016-10-28 16:54:03 +02:00
f3e791d1ac Ticket #1034 : leave note at dlclose() call 2016-10-28 16:54:02 +02:00
12f1165765 Inv(#1020): add code to monitor clean-up by GTK
I am still suspicious the cleanup mechanism for child widgets works as expected...
But right now, we can't verify that, since on shutdown we get an assertion failure
from ld.so "dl-close.c: 762: _dl_close: Assertion `map->l_init_called' failed!"
Seems we're loading the GUI plugin not properly
2016-10-27 23:36:20 +02:00
dd9f34e93a Inv(#1020): prepare Investigation
- define tasks to be addressed during investigation
- read documentation, identify problematic aspects
- prepare a child widget class to be placed on the canvas
2016-10-27 22:57:46 +02:00
2350998fdb setup layout for experiments (closes #1021) 2016-10-27 04:15:20 +02:00
0888e0afe7 new empty dock for research and experiments (#1020)
My intention is to use this space for experiments first,
and then as a construction site for a rewrite of the
custom timeline widget.

We really need a rewrite here, in order to be properly
aligned to the standard way of writing such a custom widget,
and also to build our first connection to the UI-Bus and then
remove the old placeholder UI model
2016-10-27 02:57:23 +02:00
3bb76f2f2c move asside old code to make room for investigation
...goal is to have a new dockable panel,
where we'll build the new timeline widget eventually.

Signed-off-by: Ichthyostega <prg@ichthyostega.de>
2016-10-26 18:44:27 +02:00
c8b6e7a699 mark some code smells (#1026) 2016-10-26 18:44:27 +02:00
2d8a595038 Finish AbstractTangible_test and the basic UI-Element protocol
closes #975 and #992
2016-10-04 03:50:44 +02:00
22f06dca23 Bugfix: must init TreeMutator explicitly now
as consequence of previous fix.
Also, when building the preconfigured TreeMutator for GenNode,
the init hook must be called explicitly now.
2016-10-04 03:24:44 +02:00
1725a31df1 Bugfix: insidious dangling pointer caused by move after construction
Damn sideeffect of the suppport for move-only types: since we're
moving our binding now into place /after/ construction, in some cases
the end() iterator (embedded in RangeIter) becomes invalid. Indeed this
was always broken, but didn't hurt, as long as we only used vectors.

Solution: use a dedicated init() hook, which needs to be invoked
*after* the TreeMutator has been constructed and moved into the final
location in the stack buffer.
2016-10-03 23:54:09 +02:00
bada8ecffd TreeMutator binding: fix collection binding to support move-only types
unintentionally we used copy construction in the builder expression,
wenn passing in the CollectionBinding to the ChildCollectionMutator.

The problem is that CollectionBinding owns a shaddow buffer, where
the contents of the target collection are moved temporarily while
applying the diff. The standard implementation of copy construction
would cause a copy of that shaddow buffer, which boils down to
a copy of the storage of the target collection.

If we want to support move-only types in the collection, most notably
std::unique_ptr, we can thus only use the move constructor. Beyond that
there is no problem, since we're only ever moving elements, and new
elements will be move constructed via emplace() or emplace_back()
2016-10-03 20:08:54 +02:00
d58f8c853a TreeMutator binding: extend collection binding to support std::map
actually this is a pragmatic extension for some special use cases,
and in general rather discurraged, since it contradicts the
established diff semantics. Yet with some precaution, it should
be possible to transport information via an intermediary ETD

Map -> ETD -> Map
2016-10-03 19:31:59 +02:00
15ac0d6310 clean-up: remove one leftover of Ref::THIS (#996)
for the record: while it is indeed sweet-and-simple to support Ref::THIS
here, it is near impossible to represent it in general, in a setup with
multiple "onion-layers". The reason is, we'd have to incorporate such
special treatment into the /selector predicate/, which in turn undermines
the ability to pick the right onion layer to handle a given diff verb,
since "Ref::THIS" is a generic marker and we have no other data to base
the decision in the selector on.
2016-10-03 17:33:30 +02:00
ffcfa7afd4 WIP: draft a concrete TreeMutator binding for MockElm
...this is the first attempt to integrate the Diff-Framework into (mock) UI code.
Right now there is a conceptual problem with the representation of attributes;
I tend to reject idea of binding to an "attribute map"
2016-10-03 01:59:47 +02:00
c8ad698ac4 MutationMessage: limit to treating of gui::model::Tangible
the generic typing to DiffMutatble does not make much sense,
since the desired implementation within gui::ctrl::Nexus
is bound to work on Tangibles only, since that is what
the UI-Bus stores in the routing table
2016-10-02 23:51:45 +02:00
b251b9a022 MutationMessage: generic implementation based on the DiffMutable interface 2016-10-02 23:34:07 +02:00
76fc444437 MutationMessage: implementation draft 2016-10-02 22:21:17 +02:00
f0de986399 Library: allow to immediately emplace a subclass type into InPlaceBuffer
Up to now, InPlaceBuffer used to default construct an instance of the
Interface class, and then you'd need to invoke the `create()` function
to actually create the desired subclass. This is not only inefficient,
but rules out the use of abstract interfaces / base classes.

Unfortunately, there is no way in C++ to specify an explicit template argument list
on ctor calls, so we resort to the trick of passing an additional dummy marker argument
2016-10-02 22:15:55 +02:00
d2e4f826ed UI-Bus/mutation: expand on draft for mutation message 2016-10-01 23:09:08 +02:00
d87111f703 DOC: MutationMessage 2016-10-01 22:36:52 +02:00
27ba8d5896 UI-Bus/mutation: draft idea for mutation message on UI-Bus 2016-09-30 22:23:55 +02:00
6c3024adcd UI-Bus/mutation: search for ways how to integrate Diff processing 2016-09-30 18:13:04 +02:00
2a26cef010 remove leftovers of first diff-applicator implementation
...obsoleted by new generic implementation
2016-09-08 18:30:27 +02:00
4267d3d1d7 application via TreeMutator is now the default
remove the intermediary header
2016-09-05 04:36:07 +02:00
a066650eb7 remove the now obsolete, dedicated first diff implementation
yay! this piece of code has served its purpose:
it was the blueprint to build a way better design and implementation,
which can now cover this "generic tree" case as a special case as well
2016-09-05 04:05:31 +02:00
840d9e4397 make Rec::Mutator as such diff mutable
this adds kind of an extension point to diff::Record<GenNode>::Mutator,
which is then actually defined (implemented) within the diff framework.

This allows the TreeDiffTraits automatically to use this function
to get a TreeMutator for a given Rec::Mutator. Which in turn allows
the generic version of DiffApplicator automatically to attach and
bind to a Record<GenNode>

together this allows us to ditch the explicit specialisation
and dedicated, hand-written implementation of DiffApplication
to GenNode in favour of using the TreeMutator and friends.
2016-09-05 02:25:07 +02:00
ebb3ccb589 clean-up: move PlantingHandle over to the OpaqueHolder facility
...where it belongs; it is entirely generic
and we'd expect more usage on APIs for callbacks
2016-09-04 23:21:15 +02:00
5c0baba2eb finish implementation of GenNode - TreeMutator binding
some minor code clean-up and comments;
the solution dafted yesterday is the way to go.
2016-09-04 20:55:21 +02:00
17f8922775 solution (draft) for the type field problem
unit test PASS

but the resulting code is hard to understand
should refactor it to use a binding class
similar to the other binding cases
2016-09-03 22:34:36 +02:00
a73e5ffffe TreeMutator binding: change handling of AFTER(Ref::ATTRIBS)
this is a subtle change in the semantics of the diff language,
actually IMHO a change towards the better. It was prompted by the
desire to integrate diff application onto GenNode-trees into the
implementation framework based on TreeMutator, and do away with
the dedicated implementation.

Now it is a matter of the *selector* to decide if a given layer
is responsible for "attributes". If so, then *all* elements within
this layer count as "attribute" and an after(Ref::ATTRIBS) verb
will fast forward behind *the end of this layer*

Note that the meta token Ref::ATTRIBS is a named GenNode,
and thus trivially responds to isNamed() == true
2016-09-02 18:40:16 +02:00
05768e4ac5 first part of unit-test for GenNode TreeMutator-binding PASS
needed to use a forward function declaration within the
lambda for recursive scope mutator building, since otherwise
everything is inline and thus the compilation fails when it
comes to deducing the auto return type of the builder.

Other than that, the whole mechanics seem to work out of the box!
2016-09-02 03:10:27 +02:00
e00d6c2a4c reorganise inclusion of TreeMutator-DSL builders
previously they where included in the middle of tree-mutator.hpp
This was straight forward, since the builder relies on the classes
defined in the detail headers.

However, the GenNode-binding needs to use a specifically configured
collection binding, and this in turn requires writing a recursive
lambda to deal with nested scopes. This gets us into trouble with
circular definition dependencies.

As a workaround we now only *declare* the DSL builder functions
in the tree-mutator-builder object, and additionally use auto on
all return types. This allows us to spell out the complete builder
definition, without mentioning any of the implementation classes.
Obviously, the detail headers have then to be included *after*
the builder definition, at bottom of tree-mutator.hpp
This also allows us to turn these implementation headers into
completely normal headers, with namespaces and transitive #includes

In the end, the whole setup looks much more "innocent" now.

But beware: the #include of the implementation headers at bottom
of tree-mutator.hpp needs to be given in reverse dependency order,
due to the circular inclusion (back to tree-mutator.hpp) in
conjunction with the inclusion guards!
2016-09-02 01:29:32 +02:00
f907ff05d6 WIP: define binding behaviour for diff->GenNode
...need still to solve a problem with circular definition dependencies
2016-09-01 22:58:08 +02:00
c791763890 implement builder setup for Rec<GenNode>
this compiles just fine.
But we still need to define the concrete closures
to make it work with the actual contents of GenNode
2016-08-31 18:40:09 +02:00
a01435f367 WIP: outline of a new GenNode binding
...instead of using a hand written implementation,
the idea is to rely on the now implemented building blocks,
with just some custom closures to make it work.
2016-08-31 17:09:32 +02:00
3774960dcc finish and document some loose ends
...with the exception of a GenNode binding, the whole
diff application and binding framework is now built and ready for use
2016-08-29 22:14:03 +02:00
ffd40d86e7 finish integration test and TreeMutator binding (#992)
This implementation draft is now roughly complete
2016-08-29 19:39:19 +02:00
2814276387 a better name for the complex integration test 2016-08-29 17:52:35 +02:00
77ada853a2 verify and clean-up implementation diff application through TreeMutator
- esp. verify the proper inclusion of the Selector closure in all Operations
- straighten the implementation of Attribute binding
- clean-up the error checking helpers
2016-08-26 16:29:50 +02:00
22281d7323 deal with a mismatch between diff language and impl situation
- for sake of consistency, diff language requires INS
- but typically, that implementation will be NOP
2016-08-26 02:56:48 +02:00
fe4b46ad7c implement mutation of nested scopes 2016-08-26 02:42:19 +02:00
1b6a87324d implement value assignment through TreeMutator 2016-08-25 18:42:51 +02:00
cc91e5bba6 implement rest of the list diff verbs plus accept-until construct
basically just assembling the ready made building blocks now...
2016-08-25 17:48:40 +02:00
66022d623d reorder test definition accordingly: mutateAttribute()
similar reordering for the third part.
This time most operations are either passed down anyway,
or are NOP, since attribute binding has no notion of 'order'
2016-08-13 19:03:42 +02:00
4ea5b0d308 reorder test definition accordingly: mutateCollection()
similar reordering for the second part of the test...
2016-08-13 18:34:52 +02:00
e1687c1c18 supply missing implementation for after(Ref::ATTRIBS) to TestMutationTarget
yay! unit testing rocks.
Actually I changed the test definition for another reason, just to discover
that I've missed to implement that operation in this onion layer
2016-08-13 17:34:57 +02:00
c027ce4638 implement list diff verbs pick, del, find and skip.
now failing due to a contradiction in test fixture:
it is nonsensical to re-order attributes; rather, we should
cover re-ordering of children, to verify that the mutator binding
properly surpasses the attribute layers and forwards operations
to the lower layers responsible for handling child scopes...
2016-08-10 03:29:32 +02:00
0782dd4922 investigate and confirm the logic underlying the matchSrc, skipSrc and acceptSrc primitives
In Theory, acceptSrc and skipSrc are to operate symmetrically,
with the sole difference that skipSrc does not move anything
into the new content.

BUT, since skipSrc is also used to implement the `skip` verb,
which serves to discard garbage left back by a preceeding `find`,
we cannot touch the data found in the src position without risk
of SEGFAULT. For this reason, there is a dedicated matchSrc operation,
which shall be used to generate the verification step to properly
implement the `del` verb.

I've spent quite some time to verify the logic of predicate evaluation.
It seems to be OK: whenever the SELECTOR applies, then we'll perform
the local match, and then also we'll perform the skipSrc. Otherwise,
we'll delegate both operations likewise to the next lower layer,
without touching anything here.
2016-08-09 23:42:42 +02:00
43f3560b15 get the first diff verb to work
surprise surprise, no catastrophe thus far....
2016-08-08 14:20:54 +02:00
6e829e3f22 guard applicability by selector predicate
OMG ... this can't possibly work???!
2016-08-07 01:58:26 +02:00
18c9f95cbe integrate the first diff verb 'ins'
--> now it becomes obvious that we've mostly
missed to integrate the Selector predicate properly
in most bindings defined thus far. Which now causes
the sub-object binding to kick in, while actually
the sub-value collection should have handled
the nested values CHILD_B and CHILD_T
2016-07-31 00:33:26 +02:00
cbdc53e2d8 define a TreeMutator binding for our test::Opaque type
OMG, this is intricate stuff....
Questionable if anyone (other than myself) will be able
to get those bindings right???

Probably we'll need yet another abstraction layer to handle
the most common binding situations automatically, so that people
can use the diff framework without intricate knowledge of
TreeMutator construction.
2016-07-31 00:33:26 +02:00
2b424be57c deprecate planned Option monad
...since C++17 will likely ship an option type with the standard library
2016-07-31 00:33:26 +02:00
cbe29fead3 Library: allow for pretty-printing of smart-ptr values
- an extension to our custom toString and typeString helpers.
- currently just for shared_ptr and unique_ptr
- might add further overloads for other smart-ptr types
2016-07-31 00:33:26 +02:00
52918b069f metaprogramming: trait to detect smart-pointers 2016-07-31 00:33:26 +02:00
020940545c integrate the complete initialisation sequence
when about to consume the next diff sequence, the
scopeStack will be reset and a new root scope TreeMutator
will be placed into this top buffer
2016-07-31 00:33:26 +02:00
17c78f369c ScopeManager stack based implementation
integrated into the generic DiffApplicationStrategy.
The dedicated, explicit specialisation for DiffMutable is
no longer needed, since the generic template will degrade or
fall back to precisely this functionality, when the target
implements the DiffMutable interface
2016-07-31 00:33:26 +02:00
a7b5a88c60 integrate size traits and ScopeManager implementation 2016-07-31 00:33:25 +02:00
d1bbf01029 solution to integrate heap based storage for nested scopes 2016-07-31 00:33:25 +02:00
78c9b0835e solution draft for integration of the whole tree diff application machinery
This is the first skeleton to combine all the building blocks,
and it passes compilation, while of course most of the binding
implementation still needs to be filled in...
2016-07-31 00:33:25 +02:00
ed18e1161c WIP: code organisation - double layered architecture 2016-07-31 00:33:19 +02:00
40b032c9c2 WIP: code organisation - declaration and definition 2016-07-25 15:21:30 +02:00
0d2335c9ed WIP: code organisation - create dedicated implementation unit
It occurred to me, that 90% of this template specialisation
are entirely generic and not dependant on the actual target type.
While the compiler/linker is able to sort such a situation out,
this might lead to template bloat and possibly subtle errors.

So it seems more adequate to emit the generic part of the code
right away from within a dedicated translation unit within the
library module; so the vtable is already in place and only
the flexible part of the code needs to be re-emitted on
each usage site.
2016-07-24 15:16:06 +02:00
4a2340ca5e solution for access to "tree mutator building closure"
- default recommendation is to implement DiffMutable interface
- ability to pick up similar non-virtual method on target
- for anything else client shall provide free function mutatorBinding(subject)


PERSONAL NOTE: this is the first commit after an extended leave,
where I was in hospital to get an abdominal cancer removed.
Right now it looks like surgery was successful.
2016-07-21 19:29:16 +02:00
5744244f73 considerations how to access the "tree mutator building closure"
this is at the core of the integration problem: how do we expose
the ability of some opaque data structure to create a TreeMutator?

The idea is
 - to use a marker/capability interface
 - to use template specialisation to fabricate an instance of that interface
   based on the given access point to the opaque data structure
2016-06-14 02:33:28 +02:00
61627b26a0 WIP: first attempt to use a TreeMutator based binding
but unfortunately this runs straight into a tough problem,
which I tried to avoid and circumvent all the time:
At some point, we're bound to reveal the concrete type
of the Mutator -- at least to such an extent that we're
able to determine the size of an allocator buffer.

Moreover, by the design chosen thus far, the active
TreeMutator instance (subclass) is assumed to live within
the top-level of a Stack, which means that we need to
place-construct it into that location. Thus, either
we know the type, or we need to move it into place.
2016-06-11 19:40:53 +02:00
57b105bbc5 fix a re-entrance problem
initially, even the diff applicator was meant to be a
"throwaway" object. But then, on writing some tests,
it seemed natural to allow re-using a single applicator,
after having attached it to some target.

With that change, I failed to care for the garbage
left back in the "old" sequence after applying one diff;
since in the typical usage sequence, the first use builds
content from scratch, this problem starts to show up only
with the third usage, where the garbage left from the input
of the second usage appears at the begin of the "new sequence"

Solution is to throw away that garbage explicitly on re-entrance
2016-06-10 02:48:22 +02:00
6fa54411b3 improved log msg
..because actually we don't know if the intention is
to drop those waste elements -- and for sure this
discarding of waste does not happen through the
invocation logged here; rather it happens by
abandoning the scope
2016-06-09 01:21:06 +02:00
37cfdbb7e1 better name for nested handle type 2016-06-09 01:18:21 +02:00
ef27c09fa2 round-up and document the attribute binding and test 2016-06-09 01:10:52 +02:00
b5ab5df929 supply implementation, basically working already
so this test case is more or less finished,
just needs some more polishing and documentation
2016-06-05 17:26:48 +02:00
6eff16f21c supply missing implementation
standard case of attribute binding, i.e.
the setter invocation is fully functional now.
2016-06-05 16:31:29 +02:00
1ae3c1991d second round of this test implemented
...which mostly just is either ignoring the
operations or indicating failure on attempt to
'reorder' attributes (which don't have any notion of 'ordering')
2016-06-04 15:08:10 +02:00
76b898b602 amend the design and then implement the two concrete setter/mutator cases
overall, the structure of this implementation is still rather confusing,
yet any alternatives seem even less convincing

- if we want to avoid the delegation to base-class, we'd have
  to duplicate several functions and the combined class would
  handle two distinct concerns.
- any attempt to handle the IDs more "symmetrically" seems to
  create additional problems on one side or the other
2016-06-04 14:20:59 +02:00
ee99c405fd Reorganise implementation into base class + overlay
...as preparation for implementing the two flavours of
binding attributes either via  a setter lambda or via
creation of a nested mutator.
2016-05-29 03:01:27 +02:00
e5bbcb27d8 identify attributes through an EntryID (including type hash)
this also supersedes and removes the initial implementation
draft for attribute binding with the 'setAttribute' API
The elementary part of diff application incl. setting
new attribute values works by now.
2016-05-28 03:41:03 +02:00
5dbe877318 Library: add option to bypass the sanitising in EntryID
While in general it is fine to clean-up any entity IDs
to be US-ASCII alphanumerics (plus some allowed interpunction),
the GenNodes and also keys in object-bindings for diff are
considerd internal interfaces, assuming that any passed
ID symbol is already sanitised and checked. So the
sanitise operation can be skipped. This changeset
adds the same option directly to lib::EntryID,
allowing to create an EntryID that matches
a similar GenNode's (hash) ID.
2016-05-28 03:21:04 +02:00
16086caf42 explicit error message
...turns out that inclusion of format-string.hpp
is almost irrelevant, since diff/record.hpp already
includes even format-util.hpp
2016-05-28 01:49:03 +02:00
201b6542f2 API change to allow to detect missing attribute binding
The way we build this attribute binding, there is no single
entity to handle all attribute bindings. Thus the only way
to detect a missing binding is when none of the binding layers
was able to handle a given INS verb
2016-05-28 01:17:45 +02:00
4073cdf797 first part of the implementation of attribute binding
...the simple checks and direct assignment.
Passes compiler, but test fails where it shouldn't
2016-05-27 03:33:56 +02:00
34f6d38919 WIP: implant outline of the implementation
...again by overriding all TreeMutator operations
2016-05-27 02:08:29 +02:00
06102b74ad rename test (no change) 2016-05-26 02:16:34 +02:00
4571d3fb0f introduce new mutation primitive as pointed out by preceding analysis
to summarise, it turned out that it is impossible to
provide an airtight 'emptySrc' implementation when binding
to object fields -- so we distinguish into positive and
negative tests, allowing to loosen the sanity check
only for the latter ones when binding to object fields.
2016-05-24 23:43:55 +02:00
b47b4c3f94 flip logic of emptySrc -> hasSrc
..as concluded from the preceding analysis.
NOTE this entails a semantical change, since this
predicate is now only meant to be indicative, not conclusive

remarks: the actual implementation of the diff application process
as bound via the TreeMutator remains yet to be written...
2016-05-24 21:34:08 +02:00
72f9b4edb1 Analysis continued: inner contradictions of object field vs attribute
...after re-reading my own documentation, it occured to me that
we need to draw a border line and thus decide, what not to support
2016-05-21 17:55:48 +02:00
d3869d2280 Design/Analysis: Attribute TreeMutator binding
how can ordinary object fields be treated as "Attributes"
and thus tied into the Diff framework defined thus far.
This turns out to be really tricky, even questionable
2016-04-30 00:26:19 +02:00
835c43027d add support for Ref::THIS (questionable, #996)
while simple to add into the implementation, this whole feature
seems rather qestionable to me now, thus I've added a Ticket
to be revisited later.

In a nutshell, right here, when implementing the binding layer
for STL collections, it is easy to enable the framework to treat
Ref::THIS properly, but the *actual implementation* will necessarily
be offloaded onto each and every concrete binding implementation.
Thus client code would have to add support for an rather obscure
shortcut within the Diff language. The only way to avoid this
would be to change the semantics of the "match"-lambda: if this
binding would rather be a back-translation of implementation data
into GenNode::ID values, then we'd be able to implement Ref::THIS
natively. But such an approach looks like a way inferiour deisgn
to me; having delegated the meaning of a "match" to the client
seems like an asset, since it is both natural and opens a lot
of flexibility, without adding complexity.

For that reason I tend to avoid that shortcut now, in the hope
to be able to drop it entirely from the language
2016-04-18 01:21:38 +02:00
7bbfb4bc68 implement nested mutation of sub structures
...basically this worked right away and was easy to put together.
However, when considering how many components, indirections and
nested lambdas are working together here, I feel a bit dizzy...

:-/
2016-04-17 04:51:19 +02:00
69c63045e6 DOC: constituting elements of the TreeMutator
write down a first draft for a definiton section,
to describe the fundamental parts involved, when
applying a diff message onto implementation defined
data structures

After a break of tree weeks, I found it difficult to find may way
amidst all those various levels of abstraction. In addition to this
definition, we'll probably also need a high level overview of the
whole diff system operation.
2016-04-17 03:53:10 +02:00
8167fbff77 implement fast-forward and assignment to value
...all of this implementation boils down to slightly adjusting
the code written for the test-mutation-target. Insofar it pays off now
having implemented this diagnostic and demonstration first.

Moreover I'm implementing this basic scheme of "diff application"
roughly the fourth time, thus things kindof fall into place now.
What's really hard is all those layers of abstraction in between.

Lesson learned (after being off for three weeks, due to LAC and
other obligations): I really need to document the meaning of the
closures, and I need to document the "abstract operational semantics"
of diff application, otherwise no one will be able to provide
the correct closures.
2016-04-17 01:07:07 +02:00
7f42b9b7e7 draft third round of mutation operations to be implemented
...now about opening a sub mutator within a nested scope
2016-04-16 02:20:23 +02:00
54fb335a9c allow to "peek" into an embedded Record's type field
while I still keep my stance not to allow reflection and
switch-on-type, access to the internal / semantic type of
an embedded record seems a valid compromise to allow
to deal with collections of object-like children
of mixed kind.

Indirectly (and quite intentional) this also opens a loophole
to detect if a given GenNode might constitute a nested scope,
but with the for the actual nested element indeed to cary
a type symbol. Effectively this limits the use of this shortcut
to situations where the handling context does have some pre-established
knowledge about what types *might* be expected. This is precisely
the kind of constraint I intend to uphold: I do not want the
false notion of "total flexibility", as is conveyed by introspection.
2016-04-16 00:48:15 +02:00
ad6d348d8f make TreeMutator noncopyable to prevent dangling references
since we're moving elements around to apply the diff,
dangerous situation might arise in case anyone takes a copy
of the mutator. Thus we effectively limit the possible
usage pattern and only allow to build an anonymous
TreeMutator subclass through the Builder-DSL.

The concrete "onion layers" of the TreeMutator are now limited
- to be created by the chaining operations of the Builder DSl
- to be moved into target location, retaining ownership.
2016-03-26 02:01:31 +01:00
f9f2a225c3 implement content reordering mutation primitives
and cover result in test.
This also demonstrates that it is possible to install
a specific lambda on each usage
2016-03-26 01:22:40 +01:00
c49dd04b44 address an insidious dangling reference
I still feel somewhat queasy with this whole situation!
We need to return the product of the DSL/Builder by value,
but we also want to swap away the current contents before
starting the mutation, and we do not want a stateful lifecycle
for the mutator implementation. Which means, we need to swap
right at construction, and then we copy -- TADAAA!

Thus I'm going for the solution to disallow copying of the
mutator, yet to allow moving, and to change the builder
to move its product into place. Probably should even push
this policy up into the base class (TreeMutator) to set
everyone straight.

Looks like this didn't show up with the test dummy implementation
just because in this case the src buffer also lived within th
TestMutationTarget, which is assumed to sit where it is, so
effectively we moved around only pointers.
2016-03-26 00:48:38 +01:00
d98fde5b0e better verification in test
...actually iterate the populated collection
and verify each element in order. Also verify
and document the mutator's storage requirements
2016-03-25 23:12:54 +01:00
e84844142f implement inserting of new elements 2016-03-25 22:43:11 +01:00
91bf75d54a spelling in comments 2016-03-25 21:40:30 +01:00